forked from tcnksm/go-input
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ask.go
92 lines (75 loc) · 1.98 KB
/
ask.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package input
import (
"bytes"
"fmt"
)
// Ask asks the user for input using the given query. The response is
// returned as string. Error is returned based on the given option.
// If Loop is true, it continue to ask until it receives valid input.
//
// If the user sends SIGINT (Ctrl+C) while reading input, it catches
// it and return it as a error.
func (i *UI) Ask(query string, opts *Options) (string, error) {
i.once.Do(i.setDefault)
// Display the query to the user.
fmt.Fprintf(i.Writer, "%s", query)
// resultStr and resultErr are return val of this function
var resultStr string
var resultErr error
loopCount := 0
for {
loopCount++
// Construct the instruction to user.
var buf bytes.Buffer
if !opts.HideOrder || loopCount > 1 {
buf.WriteString("\nEnter a value")
}
if opts.Default != "" && !opts.HideDefault {
defaultVal := opts.Default
if opts.MaskDefault {
defaultVal = maskString(defaultVal)
}
buf.WriteString(fmt.Sprintf(" (Default is %s)", defaultVal))
}
// Display the instruction to user and ask to input.
buf.WriteString(": ")
fmt.Fprintf(i.Writer, buf.String())
// Read user input from UI.Reader.
line, err := i.read(opts.readOpts())
if err != nil {
resultErr = err
break
}
// line is empty but default is provided returns it
if line == "" && opts.Default != "" {
resultStr = opts.Default
break
}
if line == "" && opts.Required {
if !opts.Loop {
resultErr = ErrEmpty
break
}
fmt.Fprintf(i.Writer, "Input must not be empty.\n\n")
continue
}
// validate input by custom fuction
validate := opts.validateFunc()
if err := validate(line); err != nil {
if !opts.Loop {
resultErr = err
break
}
fmt.Fprintf(i.Writer, "Failed to validate input string: %s\n\n", err)
continue
}
// Reach here means it gets ideal input.
resultStr = line
break
}
// Insert the new line for next output
if !opts.SkipNewline {
fmt.Fprintf(i.Writer, "\n")
}
return resultStr, resultErr
}