Error handeling by means of errors.Is

This commit is contained in:
Foil-hat-guy 2025-05-05 00:00:56 +03:00
parent 9acae0ee0c
commit a4eb5389e0
No known key found for this signature in database
GPG key ID: 221CC305A7B23591
4 changed files with 122 additions and 51 deletions

17
dummy.go Normal file
View file

@ -0,0 +1,17 @@
package stty
type dummy struct{
err error
}
func (d *dummy) SetBaudRate(portPath string, baudrate int) error {
return d.err
}
func (d *dummy) CheckBaudRate(portPath string) (baudrate int, err error) {
return 0, d.err
}
func (d *dummy) TestBaudRate(portPath string, baudrate int) error {
return d.err
}

37
error.go Normal file
View file

@ -0,0 +1,37 @@
package stty
import(
"fmt"
)
func errStack(err1 error, err2 error) error {
return fmt.Errorf("%w: %w", err1, err2)
}
func ERR_NOT_TTY() error {
return fmt.Errorf("File is not a tty")
}
func ERR_CANNOT_OPEN_FILE() error {
return fmt.Errorf("Can not open file")
}
func ERR_NO_WRITE_ACCESS() error {
return fmt.Errorf("No write access")
}
func ERR_STTY_MISSING() error {
return fmt.Errorf("Stty is missing")
}
func ERR_BAUDRATE_NOT_SUPPORTED() error {
return fmt.Errorf("Selected baudrate is not supported")
}
func ERR_SET_BAUDRATE_FAILED() error {
return fmt.Errorf("Failed to set baudrate using stty")
}
func ERR_CHECK_BAUDRATE_FAILED() error {
return fmt.Errorf("Failed to check baudrate using stty")
}

46
real.go Normal file
View file

@ -0,0 +1,46 @@
package stty
import(
"os/exec"
"fmt"
)
type real struct {
}
func (r *real) SetBaudRate(portPath string, baudrate int) error {
setBaudRateCMD := exec.Command("stty", "-F", portPath, fmt.Sprint(baudrate))
_, err := setBaudRateCMD.Output()
return errStack(ERR_SET_BAUDRATE_FAILED(), err)
}
func (r *real) CheckBaudRate(portPath string) (baudrate int, err error) {
checkBaudRateCMD := exec.Command("stty", "-F", portPath, "speed")
sttyOutput, err := checkBaudRateCMD.Output()
if err != nil {
return 0, err
}
_, err = fmt.Sscan(string(sttyOutput), &baudrate)
if err != nil {
return 0, err
}
return baudrate, nil
}
func (r *real) TestBaudRate(portPath string, baudrate int) error {
err := r.SetBaudRate(portPath, baudrate)
if err != nil {
return err
}
newBaudRate, err := r.CheckBaudRate(portPath)
if err != nil {
return errStack(ERR_CHECK_BAUDRATE_FAILED(), err)
}
if newBaudRate == baudrate {
return nil
}
return ERR_BAUDRATE_NOT_SUPPORTED()
}

73
stty.go
View file

@ -1,76 +1,47 @@
package stty
import (
"fmt"
"os"
"golang.org/x/sys/unix"
"golang.org/x/term"
"os/exec"
)
type stty struct {
type stty interface{
SetBaudRate(portPath string, baudrate int) error
CheckBaudRate(portPath string) (baudrate int, err error)
TestBaudRate(portPath string, baudrate int) error
}
var cmd stty
func CMD() stty {
return cmd
}
func init() {
checkSttyCMD := exec.Command("stty", "--version")
sttyOutput, err := checkSttyCMD.Output()
if err != nil || len(sttyOutput) == 0 {
cmd = &dummy{errStack(ERR_STTY_MISSING(),err)}
}
cmd = &real{}
}
func ValidateTtyFile(filepath string) error {
file, err := os.Open(filepath)
if err != nil {
return err
return errStack(ERR_CANNOT_OPEN_FILE(), err)
}
defer file.Close()
err = unix.Access(filepath, unix.W_OK)
if err != nil {
return err
return errStack(ERR_NO_WRITE_ACCESS(), err)
}
if term.IsTerminal(int(file.Fd())) {
return nil
}
return fmt.Errorf("File is not a tty.")
}
func Get() (*stty, error) {
checkSttyCMD := exec.Command("stty", "--version")
sttyOutput, err := checkSttyCMD.Output()
if err != nil || len(sttyOutput) == 0 {
return nil, fmt.Errorf("Stty is missing. Because: " + err.Error())
}
return &stty{}, nil
}
func (s *stty) SetBaudRate(portPath string, baudrate int) error {
setBaudRateCMD := exec.Command("stty", "-F", portPath, fmt.Sprint(baudrate))
_, err := setBaudRateCMD.Output()
return err
}
func (s *stty) CheckBaudRate(portPath string) (baudrate int, err error) {
checkBaudRateCMD := exec.Command("stty", "-F", portPath, "speed")
sttyOutput, err := checkBaudRateCMD.Output()
if err != nil {
return 0, fmt.Errorf("Failed to invoke stty. Because: " + err.Error())
}
_, err = fmt.Sscan(string(sttyOutput), &baudrate)
if err != nil {
return 0, fmt.Errorf("Failed to read baudrate from stty output. Because:" + err.Error())
}
return baudrate, nil
}
func (s *stty) TestBaudRate(portPath string, baudrate int) (error) {
err := s.SetBaudRate(portPath, baudrate)
if err != nil {
return fmt.Errorf("Failed to set baudrate using stty. Because: " + err.Error())
}
newBaudRate, err := s.CheckBaudRate(portPath)
if err != nil {
return fmt.Errorf("Failed to check baudrate using stty. Because: " + err.Error())
}
if newBaudRate == baudrate {
return nil
}
return fmt.Errorf("Selected baudrate is not supported.")
return ERR_NOT_TTY()
}