package ask import ( "bufio" "fmt" "os" "strings" ) func raw[T any](query string, to byte, validate func(string) (v T, msg string)) T { fmt.Println(query) reader := bufio.NewReader(os.Stdin) for { text, _ := reader.ReadString(to) v, msg := validate(strings.TrimSpace(text[:len(text)-1])) if msg == "" { return v } fmt.Println(msg) } } func String(query string, min, max int) string { return raw(query, '\n', func(s string) (v string, msg string) { v = s if min >= 0 && len(v) < min { msg = fmt.Sprintf("your input is to short. Minimum length is %d", min) return v, msg } if max >= 0 && len(v) > max { msg = fmt.Sprintf("your input is to long. Maximum length is %d", min) return v, msg } return v, msg }) } func StringSlice(query string, min, max, smin, smax int) []string { return raw(query, ';', func(s string) (v []string, msg string) { splits := strings.Split(s, ",") v = make([]string, 0, len(splits)) for _, split := range splits { v = append(v, strings.TrimSpace(split)) } if min >= 0 && len(v) < min { msg = fmt.Sprintf("your input is to short. Minimum length is %d", min) } if max >= 0 && len(v) > max { msg = fmt.Sprintf("your input is to long. Maximum length is %d", max) } for i, s := range v { if smin >= 0 && len(s) < smin { msg = fmt.Sprintf("your is value at index %d is to short. Minimum length is %d", i, smin) } if smax >= 0 && len(s) > smax { msg = fmt.Sprintf("your is value at index %d is to long. Maximum length is %d", i, smax) } } return v, msg }) } func Boolean(query string, def bool) bool { if def { query += " (Y/n)" } else { query += " (y/N)" } return raw(query, '\n', func(s string) (v bool, msg string) { s = strings.ToLower(s) if s == "" { v = def return v, msg } if s == "y" { v = true return v, msg } if s == "n" { v = false return v, msg } msg = `your answer must be "y" "n" or enter for default` return v, msg }) }