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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
/*
Package input reads user input at the console. http://github.com/tcnksm/go-input
ui := &input.UI{
Writer: os.Stdout,
Reader: os.Stdin,
}
query := "What is your name?"
name, err := ui.Ask(query, &input.Options{
Default: "tcnksm",
Required: true,
Loop: true,
})
*/
package input
import (
"bufio"
"errors"
"io"
"os"
"sync"
)
var (
// defaultWriter and defaultReader is default val for UI.Writer
// and UI.Reader.
defaultWriter = os.Stdout
defaultReader = os.Stdin
// defualtMaskVal is default mask val for read
defaultMaskVal = "*"
)
var (
// Errs are error returned by input functions.
// It's useful for handling error from outside of input functions.
ErrEmpty = errors.New("default value is not provided but input is empty")
ErrNotNumber = errors.New("input must be number")
ErrOutOfRange = errors.New("input is out of range")
ErrInterrupted = errors.New("interrupted")
)
// UI is user-interface of input and output.
type UI struct {
// Writer is where output is written. For example a query
// to the user will be written here. By default, it's os.Stdout.
Writer io.Writer
// Reader is source of input. By default, it's os.Stdin.
Reader io.Reader
// mask is option for read function
mask bool
maskVal string
bReader *bufio.Reader
once sync.Once
}
// DefaultUI returns default UI. It outputs to stdout and intputs from stdin.
func DefaultUI() *UI {
return &UI{
Writer: os.Stdout,
Reader: os.Stdin,
}
}
// setDefault sets the default value for UI struct.
func (i *UI) setDefault() {
// Set the default writer & reader if not provided
if i.Writer == nil {
i.Writer = defaultWriter
}
if i.Reader == nil {
i.Reader = defaultReader
}
if i.bReader == nil {
i.bReader = bufio.NewReader(i.Reader)
}
}
// ValidateFunc is function to validate the user input.
//
// The following example shows validating the user input is
// 'Y' or 'n' when asking yes or no question.
type ValidateFunc func(string) error
// Options is structure contains option for input functions.
type Options struct {
// Default is the default value which is used when no thing
// is input.
Default string
// Loop loops asking user to input until getting valid input.
Loop bool
// Required returns error when input is empty.
Required bool
// HideDefault hides default var output.
HideDefault bool
// HideOrder hides order comment ('Enter a value')
HideOrder bool
// Hide hides user input is prompting console.
Hide bool
// Mask hides user input and will be matched by MaskVal
// on the screen. By default, MaskVal is asterisk(*).
Mask bool
// MaskDefault hides default value. By default, MaskVal is asterisk(*).
MaskDefault bool
// MaskVal is a value which is used for masking user input.
// By default, MaskVal is asterisk(*).
MaskVal string
// ValidateFunc is function to do extra validation of user
// input string. By default, it does nothing (just returns nil).
ValidateFunc ValidateFunc
}
// validateFunc returns ValidateFunc. If it's specified by
// user it returns it. If not returns default function.
func (o *Options) validateFunc() ValidateFunc {
if o.ValidateFunc == nil {
return defaultValidateFunc
}
return o.ValidateFunc
}
// defaultValidateFunc is default ValidateFunc which does
// nothing.
func defaultValidateFunc(input string) error {
return nil
}
// readOpts returns readOptions from given the Options.
func (o *Options) readOpts() *readOptions {
var mask bool
var maskVal string
// Hide input and prompt nothing on screen.
if o.Hide {
mask = true
}
// Mask input and prompt default maskVal.
if o.Mask {
mask = true
maskVal = defaultMaskVal
}
// Mask input and prompt custom maskVal.
if o.MaskVal != "" {
maskVal = o.MaskVal
}
return &readOptions{
mask: mask,
maskVal: maskVal,
}
}
// maskString is used to mask string which should not be displayed.
func maskString(s string) string {
if len(s) < 3 {
return "*******"
}
return s[:3] + "****"
}
|