package prompt import ( "bufio" "fmt" "os" "strings" ) type Prompter interface { Prompt(string) } func Read[T any]() (out T, err error) { nilv := out b := bufio.NewReader(os.Stdin) s, err := b.ReadString('\n') if err != nil { return nilv, err } switch o := any(&out).(type) { case *string: *o = s[:len(s)-1] case *Prompter: (*o).Prompt(s) // If a number, remove all spaces before scanning case *int, *int8, *int16, *int32, *int64, *uint, *uint8, *uint16, *uint32, *uint64, *float32, *float64, *complex64, *complex128: s = strings.Replace(s, " ", "", -1) _, err = fmt.Sscan(s, o) if err != nil { return nilv, err } default: // Scan any other type, return error if it fails _, err = fmt.Sscan(s, o) if err != nil { return nilv, err } } return out, nil } func MustRead[T any]() T { out, err := Read[T]() if err != nil { panic("Error during read: " + err.Error()) } return out }