gob/shell/console/read/read.go

145 lines
3.8 KiB
Go
Raw Normal View History

2023-10-07 19:13:39 +00:00
package read
import (
"bufio"
"fmt"
"os"
"strings"
"gitea.zaclys.com/bvaudour/gob/collection"
. "gitea.zaclys.com/bvaudour/gob/option"
"gitea.zaclys.com/bvaudour/gob/shell/console"
"gitea.zaclys.com/bvaudour/gob/shell/scanner"
)
// String retourne la chaîne de caractères saisie.
func String(prompt string) Result[string] {
fmt.Print(prompt)
sc := bufio.NewScanner(os.Stdin)
if sc.Scan() {
return Ok(sc.Text())
}
return Err[string](sc.Err())
}
// Int retourne lentier saisi.
func Int(prompt string) Result[int] {
return console.PromptInt(String)(prompt)
}
// Uint retourne lentier non signé saisi.
func Uint(prompt string) Result[uint] {
return console.PromptUint(String)(prompt)
}
// Float retourne le nombre décimal saisi.
func Float(prompt string) Result[float64] {
return console.PromptFloat(String)(prompt)
}
// Bool retourne le booléen saisi.
func Bool(prompt string) Result[bool] {
return console.PromptBool(String)(prompt)
}
// Slice retourne les mots saisis.
func Slice(prompt string, t ...scanner.Tokenizer) Result[[]string] {
return console.PromptSlice(String, t...)(prompt)
}
// SliceInt retourne les entiers saisis.
func SliceInt(prompt string, t ...scanner.Tokenizer) Result[[]int] {
return console.PromptSliceInt(String, t...)(prompt)
}
// SliceUint retourne les entiers non signés saisis.
func SliceUint(prompt string, t ...scanner.Tokenizer) Result[[]uint] {
return console.PromptSliceUint(String, t...)(prompt)
}
// SliceFloat retourne les nombres décimaux saisis.
func SliceFloat(prompt string, t ...scanner.Tokenizer) Result[[]float64] {
return console.PromptSliceFloat(String, t...)(prompt)
}
// SliceBool retourne les booléens saisis.
func SliceBool(prompt string, t ...scanner.Tokenizer) Result[[]bool] {
return console.PromptSliceBool(String, t...)(prompt)
}
// Default lance une invite de commande attendant une réponse optionnelle
func Default[T any](prompt string, def T, pp console.ParsedPromptFunc[T]) (result Result[T]) {
if result = pp(prompt); !result.IsOk() {
result = Ok(def)
}
return
}
func question[T any](q string, def T, pp console.ParsedPromptFunc[T]) (result T) {
prompt := fmt.Sprintf("%s (default: %v) ", q, def)
result, _ = Default(prompt, def, pp).Ok()
return
}
// Question invite à saisir une chaîne.
// Si aucune chaîne nest saisie, def est retourné.
func Question(q string, def string) string {
return question(q, def, String)
}
// QuestionInt invite à saisir un entier.
// Si aucun entier nest saisi, def est retourné.
func QuestionInt(q string, def int) int {
return question(q, def, Int)
}
// QuestionUint invite à saisir un entier non signé.
// Si aucun entier non signé nest saisi, def est retourné.
func QuestionUint(q string, def uint) uint {
return question(q, def, Uint)
}
// QuestionFloat invite à saisir un nombre décimal.
// Si aucun nombre décimal nest saisi, def est retourné.
func QuestionFloat(q string, def float64) float64 {
return question(q, def, Float)
}
// QuestionBool invite à saisir un booléen.
// Si aucun booléen nest saisi, def est retourné.
func QuestionBool(q string, def bool) bool {
choices := "o/N"
if def {
choices = "O/n"
}
prompt := fmt.Sprintf("%s [%s] ", q, choices)
if r, ok := String(prompt).Ok(); ok && len(r) > 0 {
switch r[0] {
case 'Y', 'y', 'O', 'o', '1':
return true
case 'N', 'n', '0':
return false
}
}
return def
}
// QuestionChoice invite à saisir un chaîne parmi un choix donné.
// Si aucun choix nest effectué, retourne def.
func QuestionChoice(q string, def string, choices []string) string {
set := collection.NewSet(choices...)
prompt := fmt.Sprintf("%s [%s] (default: %v) ", q, strings.Join(choices, "|"), def)
if r, ok := String(prompt).Ok(); ok && set.Contains(r) {
return r
}
return def
}