separate options
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"gitoa.ru/go-4devs/console"
|
||||
"gitoa.ru/go-4devs/console/example/pkg/command"
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/argument"
|
||||
"gitoa.ru/go-4devs/console/input/array"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
@@ -39,10 +40,10 @@ func Command() *console.Command {
|
||||
Configure: func(ctx context.Context, def *input.Definition) error {
|
||||
def.
|
||||
SetArguments(
|
||||
input.NewArgument("test_argument", "test argument"),
|
||||
argument.New("test_argument", "test argument"),
|
||||
).
|
||||
SetOptions(
|
||||
input.NewOption("string", "array string", option.Array),
|
||||
option.New("string", "array string", option.Array),
|
||||
option.Bool("bool", "test bool option"),
|
||||
option.Duration("duration", "test duration with default", option.Default(time.Second)),
|
||||
)
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
)
|
||||
|
||||
@@ -76,36 +78,36 @@ func (t *txt) Commands(ctx context.Context, out output.Output, cmds Commands) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func txtDefaultArray(val input.Value, flag input.Flag) string {
|
||||
st := val.Strings()
|
||||
func txtDefaultArray(v value.Value, f flag.Flag) string {
|
||||
st := v.Strings()
|
||||
|
||||
switch {
|
||||
case flag.IsInt():
|
||||
for _, i := range val.Ints() {
|
||||
case f.IsInt():
|
||||
for _, i := range v.Ints() {
|
||||
st = append(st, strconv.Itoa(i))
|
||||
}
|
||||
case flag.IsInt64():
|
||||
for _, i := range val.Int64s() {
|
||||
case f.IsInt64():
|
||||
for _, i := range v.Int64s() {
|
||||
st = append(st, strconv.FormatInt(i, 10))
|
||||
}
|
||||
case flag.IsUint():
|
||||
for _, u := range val.Uints() {
|
||||
case f.IsUint():
|
||||
for _, u := range v.Uints() {
|
||||
st = append(st, strconv.FormatUint(uint64(u), 10))
|
||||
}
|
||||
case flag.IsUint64():
|
||||
for _, u := range val.Uint64s() {
|
||||
case f.IsUint64():
|
||||
for _, u := range v.Uint64s() {
|
||||
st = append(st, strconv.FormatUint(u, 10))
|
||||
}
|
||||
case flag.IsFloat64():
|
||||
for _, f := range val.Float64s() {
|
||||
case f.IsFloat64():
|
||||
for _, f := range v.Float64s() {
|
||||
st = append(st, strconv.FormatFloat(f, 'g', -1, 64))
|
||||
}
|
||||
case flag.IsDuration():
|
||||
for _, d := range val.Durations() {
|
||||
case f.IsDuration():
|
||||
for _, d := range v.Durations() {
|
||||
st = append(st, d.String())
|
||||
}
|
||||
case flag.IsTime():
|
||||
for _, d := range val.Times() {
|
||||
case f.IsTime():
|
||||
for _, d := range v.Times() {
|
||||
st = append(st, d.Format(time.RFC3339))
|
||||
}
|
||||
}
|
||||
@@ -113,32 +115,32 @@ func txtDefaultArray(val input.Value, flag input.Flag) string {
|
||||
return strings.Join(st, ",")
|
||||
}
|
||||
|
||||
func txtDefault(val input.Value, flag input.Flag) []byte {
|
||||
func txtDefault(v value.Value, f flag.Flag) []byte {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString("<comment> [default: ")
|
||||
|
||||
switch {
|
||||
case flag.IsArray():
|
||||
buf.WriteString(txtDefaultArray(val, flag))
|
||||
case flag.IsInt():
|
||||
buf.WriteString(strconv.Itoa(val.Int()))
|
||||
case flag.IsInt64():
|
||||
buf.WriteString(strconv.FormatInt(val.Int64(), 10))
|
||||
case flag.IsUint():
|
||||
buf.WriteString(strconv.FormatUint(uint64(val.Uint()), 10))
|
||||
case flag.IsUint64():
|
||||
buf.WriteString(strconv.FormatUint(val.Uint64(), 10))
|
||||
case flag.IsFloat64():
|
||||
buf.WriteString(strconv.FormatFloat(val.Float64(), 'g', -1, 64))
|
||||
case flag.IsDuration():
|
||||
buf.WriteString(val.Duration().String())
|
||||
case flag.IsTime():
|
||||
buf.WriteString(val.Time().Format(time.RFC3339))
|
||||
case flag.IsAny():
|
||||
buf.WriteString(fmt.Sprint(val.Any()))
|
||||
case f.IsArray():
|
||||
buf.WriteString(txtDefaultArray(v, f))
|
||||
case f.IsInt():
|
||||
buf.WriteString(strconv.Itoa(v.Int()))
|
||||
case f.IsInt64():
|
||||
buf.WriteString(strconv.FormatInt(v.Int64(), 10))
|
||||
case f.IsUint():
|
||||
buf.WriteString(strconv.FormatUint(uint64(v.Uint()), 10))
|
||||
case f.IsUint64():
|
||||
buf.WriteString(strconv.FormatUint(v.Uint64(), 10))
|
||||
case f.IsFloat64():
|
||||
buf.WriteString(strconv.FormatFloat(v.Float64(), 'g', -1, 64))
|
||||
case f.IsDuration():
|
||||
buf.WriteString(v.Duration().String())
|
||||
case f.IsTime():
|
||||
buf.WriteString(v.Time().Format(time.RFC3339))
|
||||
case f.IsAny():
|
||||
buf.WriteString(fmt.Sprint(v.Any()))
|
||||
default:
|
||||
buf.WriteString(val.String())
|
||||
buf.WriteString(v.String())
|
||||
}
|
||||
|
||||
buf.WriteString("]</comment>")
|
||||
|
||||
@@ -16,8 +16,8 @@ func Args() *console.Command {
|
||||
Configure: func(ctx context.Context, def *input.Definition) error {
|
||||
def.SetOptions(
|
||||
option.Bool("foo", "foo option", option.Short("f")),
|
||||
input.NewOption("bar", "required bar option", option.Required, option.Short("b")),
|
||||
input.NewOption("cat", "cat option", option.Short("c")),
|
||||
option.New("bar", "required bar option", option.Required, option.Short("b")),
|
||||
option.New("cat", "cat option", option.Short("c")),
|
||||
)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -15,7 +15,7 @@ func CreateUser(required bool) *console.Command {
|
||||
Description: "Creates a new user.",
|
||||
Help: "This command allows you to create a user...",
|
||||
Configure: func(ctx context.Context, cfg *input.Definition) error {
|
||||
var opts []func(*input.Argument)
|
||||
var opts []func(*argument.Argument)
|
||||
if required {
|
||||
opts = append(opts, argument.Required)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func Hello() *console.Command {
|
||||
},
|
||||
Configure: func(_ context.Context, def *input.Definition) error {
|
||||
def.SetArguments(
|
||||
input.NewArgument("name", "Same name", argument.Default("World")),
|
||||
argument.New("name", "Same name", argument.Default("World")),
|
||||
)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -6,9 +6,10 @@ import (
|
||||
|
||||
"gitoa.ru/go-4devs/console"
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
const defaultTimeout = time.Second * 30
|
||||
@@ -41,7 +42,7 @@ func Long() *console.Command {
|
||||
def.SetOptions(option.Duration("timeout", "set duration run command",
|
||||
option.Default(defaultTimeout),
|
||||
option.Short("t"),
|
||||
option.Valid(validator.NotBlank(input.ValueDuration)),
|
||||
option.Valid(validator.NotBlank(flag.Duration)),
|
||||
))
|
||||
|
||||
return nil
|
||||
|
||||
9
help.go
9
help.go
@@ -9,9 +9,10 @@ import (
|
||||
"gitoa.ru/go-4devs/console/descriptor"
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/argument"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
//nolint: gochecknoinits
|
||||
@@ -73,14 +74,14 @@ To display the list of available commands, please use the <info>list</info> comm
|
||||
formats := descriptor.Descriptors()
|
||||
config.
|
||||
SetArguments(
|
||||
input.NewArgument(HelpArgumentCommandName, "The command name", argument.Default("help")),
|
||||
argument.New(HelpArgumentCommandName, "The command name", argument.Default("help")),
|
||||
).
|
||||
SetOptions(
|
||||
input.NewOption(helpOptFormat, fmt.Sprintf("The output format (%s)", strings.Join(formats, ", ")),
|
||||
option.New(helpOptFormat, fmt.Sprintf("The output format (%s)", strings.Join(formats, ", ")),
|
||||
option.Required,
|
||||
option.Default(formats[0]),
|
||||
option.Valid(
|
||||
validator.NotBlank(input.ValueString),
|
||||
validator.NotBlank(flag.String),
|
||||
validator.Enum(formats...),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package input
|
||||
package argument
|
||||
|
||||
func NewArgument(name, description string, opts ...func(*Argument)) Argument {
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
)
|
||||
|
||||
func New(name, description string, opts ...func(*Argument)) Argument {
|
||||
a := Argument{
|
||||
Name: name,
|
||||
Description: description,
|
||||
@@ -16,9 +21,9 @@ func NewArgument(name, description string, opts ...func(*Argument)) Argument {
|
||||
type Argument struct {
|
||||
Name string
|
||||
Description string
|
||||
Default Value
|
||||
Flag Flag
|
||||
Valid []func(Value) error
|
||||
Default value.Value
|
||||
Flag flag.Flag
|
||||
Valid []func(value.Value) error
|
||||
}
|
||||
|
||||
func (a Argument) HasDefault() bool {
|
||||
@@ -37,12 +42,16 @@ func (a Argument) IsArray() bool {
|
||||
return a.Flag.IsArray()
|
||||
}
|
||||
|
||||
func (a Argument) Validate(v Value) error {
|
||||
func (a Argument) Validate(v value.Value) error {
|
||||
for _, valid := range a.Valid {
|
||||
if err := valid(v); err != nil {
|
||||
return ErrorArgument(a.Name, err)
|
||||
return Error(a.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Error(name string, err error) error {
|
||||
return err
|
||||
}
|
||||
@@ -1,26 +1,26 @@
|
||||
package argument
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
)
|
||||
|
||||
func Required(a *input.Argument) {
|
||||
a.Flag |= input.ValueRequired
|
||||
func Required(a *Argument) {
|
||||
a.Flag |= flag.Required
|
||||
}
|
||||
|
||||
func Default(v interface{}) func(*input.Argument) {
|
||||
return func(a *input.Argument) {
|
||||
func Default(v interface{}) func(*Argument) {
|
||||
return func(a *Argument) {
|
||||
a.Default = value.New(v)
|
||||
}
|
||||
}
|
||||
|
||||
func Flag(flag input.Flag) func(*input.Argument) {
|
||||
return func(a *input.Argument) {
|
||||
func Flag(flag flag.Flag) func(*Argument) {
|
||||
return func(a *Argument) {
|
||||
a.Flag = flag
|
||||
}
|
||||
}
|
||||
|
||||
func Array(a *input.Argument) {
|
||||
a.Flag |= input.ValueArray
|
||||
func Array(a *Argument) {
|
||||
a.Flag |= flag.Array
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
"gitoa.ru/go-4devs/console/input/wrap"
|
||||
)
|
||||
@@ -24,8 +25,8 @@ func WithErrorHandle(h func(error) error) func(*Input) {
|
||||
func New(args []string, opts ...func(*Input)) *wrap.Input {
|
||||
i := &Input{
|
||||
args: args,
|
||||
arguments: make(map[string]input.AppendValue),
|
||||
options: make(map[string]input.AppendValue),
|
||||
arguments: make(map[string]value.AppendValue),
|
||||
options: make(map[string]value.AppendValue),
|
||||
errorHandle: func(err error) error {
|
||||
return err
|
||||
},
|
||||
@@ -40,13 +41,13 @@ func New(args []string, opts ...func(*Input)) *wrap.Input {
|
||||
|
||||
type Input struct {
|
||||
args []string
|
||||
arguments map[string]input.AppendValue
|
||||
options map[string]input.AppendValue
|
||||
arguments map[string]value.AppendValue
|
||||
options map[string]value.AppendValue
|
||||
mu sync.RWMutex
|
||||
errorHandle func(error) error
|
||||
}
|
||||
|
||||
func (i *Input) ReadOption(ctx context.Context, name string) (input.Value, error) {
|
||||
func (i *Input) ReadOption(ctx context.Context, name string) (value.Value, error) {
|
||||
if v, ok := i.options[name]; ok {
|
||||
return v, nil
|
||||
}
|
||||
@@ -54,14 +55,14 @@ func (i *Input) ReadOption(ctx context.Context, name string) (input.Value, error
|
||||
return nil, input.ErrNotFound
|
||||
}
|
||||
|
||||
func (i *Input) SetOption(name string, val input.Value) {
|
||||
func (i *Input) SetOption(name string, val value.Value) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
|
||||
i.options[name] = &value.Read{Value: val}
|
||||
}
|
||||
|
||||
func (i *Input) ReadArgument(ctx context.Context, name string) (input.Value, error) {
|
||||
func (i *Input) ReadArgument(ctx context.Context, name string) (value.Value, error) {
|
||||
if v, ok := i.arguments[name]; ok {
|
||||
return v, nil
|
||||
}
|
||||
@@ -69,7 +70,7 @@ func (i *Input) ReadArgument(ctx context.Context, name string) (input.Value, err
|
||||
return nil, input.ErrNotFound
|
||||
}
|
||||
|
||||
func (i *Input) SetArgument(name string, val input.Value) {
|
||||
func (i *Input) SetArgument(name string, val value.Value) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
|
||||
@@ -129,11 +130,11 @@ func (i *Input) parseLongOption(arg string, def *input.Definition) error {
|
||||
return i.appendOption(name, value, opt)
|
||||
}
|
||||
|
||||
func (i *Input) appendOption(name string, data *string, opt input.Option) error {
|
||||
func (i *Input) appendOption(name string, data *string, opt option.Option) error {
|
||||
v, ok := i.options[name]
|
||||
|
||||
if ok && !opt.IsArray() {
|
||||
return fmt.Errorf("%w: got: array, expect: %s", input.ErrUnexpectedType, input.Type(opt.Flag))
|
||||
return fmt.Errorf("%w: got: array, expect: %s", input.ErrUnexpectedType, opt.Flag.Type())
|
||||
}
|
||||
|
||||
var val string
|
||||
|
||||
@@ -25,8 +25,8 @@ func Option(name string, v interface{}) func(*Input) {
|
||||
|
||||
func New(opts ...func(*Input)) *wrap.Input {
|
||||
i := &Input{
|
||||
args: make(map[string]input.Value),
|
||||
opt: make(map[string]input.Value),
|
||||
args: make(map[string]value.Value),
|
||||
opt: make(map[string]value.Value),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -37,12 +37,12 @@ func New(opts ...func(*Input)) *wrap.Input {
|
||||
}
|
||||
|
||||
type Input struct {
|
||||
args map[string]input.Value
|
||||
opt map[string]input.Value
|
||||
args map[string]value.Value
|
||||
opt map[string]value.Value
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (i *Input) ReadOption(_ context.Context, name string) (input.Value, error) {
|
||||
func (i *Input) ReadOption(_ context.Context, name string) (value.Value, error) {
|
||||
if o, has := i.opt[name]; has {
|
||||
return o, nil
|
||||
}
|
||||
@@ -56,13 +56,13 @@ func (i *Input) HasOption(name string) bool {
|
||||
return has
|
||||
}
|
||||
|
||||
func (i *Input) SetOption(name string, val input.Value) {
|
||||
func (i *Input) SetOption(name string, val value.Value) {
|
||||
i.mu.Lock()
|
||||
i.opt[name] = val
|
||||
i.mu.Unlock()
|
||||
}
|
||||
|
||||
func (i *Input) ReadArgument(_ context.Context, name string) (input.Value, error) {
|
||||
func (i *Input) ReadArgument(_ context.Context, name string) (value.Value, error) {
|
||||
if a, has := i.args[name]; has {
|
||||
return a, nil
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func (i *Input) HasArgument(name string) bool {
|
||||
return has
|
||||
}
|
||||
|
||||
func (i *Input) SetArgument(name string, val input.Value) {
|
||||
func (i *Input) SetArgument(name string, val value.Value) {
|
||||
i.mu.Lock()
|
||||
i.args[name] = val
|
||||
i.mu.Unlock()
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input/argument"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
)
|
||||
|
||||
func NewDefinition() *Definition {
|
||||
return &Definition{
|
||||
options: make(map[string]Option),
|
||||
args: make(map[string]Argument),
|
||||
options: make(map[string]option.Option),
|
||||
args: make(map[string]argument.Argument),
|
||||
short: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
type Definition struct {
|
||||
options map[string]Option
|
||||
options map[string]option.Option
|
||||
posOpt []string
|
||||
args map[string]Argument
|
||||
args map[string]argument.Argument
|
||||
posArgs []string
|
||||
short map[string]string
|
||||
}
|
||||
@@ -24,11 +29,11 @@ func (d *Definition) Arguments() []string {
|
||||
return d.posArgs
|
||||
}
|
||||
|
||||
func (d *Definition) SetOption(name, description string, opts ...func(*Option)) *Definition {
|
||||
return d.SetOptions(NewOption(name, description, opts...))
|
||||
func (d *Definition) SetOption(name, description string, opts ...func(*option.Option)) *Definition {
|
||||
return d.SetOptions(option.New(name, description, opts...))
|
||||
}
|
||||
|
||||
func (d *Definition) SetOptions(opts ...Option) *Definition {
|
||||
func (d *Definition) SetOptions(opts ...option.Option) *Definition {
|
||||
for _, opt := range opts {
|
||||
if _, has := d.options[opt.Name]; !has {
|
||||
d.posOpt = append([]string{opt.Name}, d.posOpt...)
|
||||
@@ -43,11 +48,11 @@ func (d *Definition) SetOptions(opts ...Option) *Definition {
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *Definition) SetArgument(name, description string, opts ...func(*Argument)) *Definition {
|
||||
return d.SetArguments(NewArgument(name, description, opts...))
|
||||
func (d *Definition) SetArgument(name, description string, opts ...func(*argument.Argument)) *Definition {
|
||||
return d.SetArguments(argument.New(name, description, opts...))
|
||||
}
|
||||
|
||||
func (d *Definition) SetArguments(args ...Argument) *Definition {
|
||||
func (d *Definition) SetArguments(args ...argument.Argument) *Definition {
|
||||
for _, arg := range args {
|
||||
if _, ok := d.args[arg.Name]; !ok {
|
||||
d.posArgs = append(d.posArgs, arg.Name)
|
||||
@@ -59,9 +64,9 @@ func (d *Definition) SetArguments(args ...Argument) *Definition {
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *Definition) Argument(pos int) (Argument, error) {
|
||||
func (d *Definition) Argument(pos int) (argument.Argument, error) {
|
||||
if len(d.posArgs) == 0 {
|
||||
return Argument{}, ErrNoArgs
|
||||
return argument.Argument{}, ErrNoArgs
|
||||
}
|
||||
|
||||
lastPos := len(d.posArgs) - 1
|
||||
@@ -71,25 +76,25 @@ func (d *Definition) Argument(pos int) (Argument, error) {
|
||||
return arg, nil
|
||||
}
|
||||
|
||||
return Argument{}, ErrToManyArgs
|
||||
return argument.Argument{}, ErrToManyArgs
|
||||
}
|
||||
|
||||
return d.args[d.posArgs[pos]], nil
|
||||
}
|
||||
|
||||
func (d *Definition) ShortOption(short string) (Option, error) {
|
||||
func (d *Definition) ShortOption(short string) (option.Option, error) {
|
||||
name, ok := d.short[short]
|
||||
if !ok {
|
||||
return Option{}, ErrNotFound
|
||||
return option.Option{}, ErrNotFound
|
||||
}
|
||||
|
||||
return d.Option(name)
|
||||
}
|
||||
|
||||
func (d *Definition) Option(name string) (Option, error) {
|
||||
func (d *Definition) Option(name string) (option.Option, error) {
|
||||
if opt, ok := d.options[name]; ok {
|
||||
return opt, nil
|
||||
}
|
||||
|
||||
return Option{}, ErrNotFound
|
||||
return option.Option{}, ErrNotFound
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package input
|
||||
|
||||
//go:generate stringer -type=Flag -linecomment
|
||||
|
||||
type Flag int
|
||||
|
||||
const (
|
||||
ValueString Flag = 0 // string
|
||||
ValueRequired Flag = 1 << iota // required
|
||||
ValueArray // array
|
||||
ValueInt // int
|
||||
ValueInt64 // int64
|
||||
ValueUint // uint
|
||||
ValueUint64 // uint64
|
||||
ValueFloat64 // float64
|
||||
ValueBool // bool
|
||||
ValueDuration // duration
|
||||
ValueTime // time
|
||||
ValueAny // any
|
||||
)
|
||||
|
||||
func (f Flag) Type() Flag {
|
||||
return Type(f)
|
||||
}
|
||||
|
||||
func (f Flag) With(v Flag) Flag {
|
||||
return f | v
|
||||
}
|
||||
|
||||
func (f Flag) IsString() bool {
|
||||
return f|ValueRequired|ValueArray^ValueRequired^ValueArray == 0
|
||||
}
|
||||
|
||||
func (f Flag) IsRequired() bool {
|
||||
return f&ValueRequired > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsArray() bool {
|
||||
return f&ValueArray > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsInt() bool {
|
||||
return f&ValueInt > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsInt64() bool {
|
||||
return f&ValueInt64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsUint() bool {
|
||||
return f&ValueUint > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsUint64() bool {
|
||||
return f&ValueUint64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsFloat64() bool {
|
||||
return f&ValueFloat64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsBool() bool {
|
||||
return f&ValueBool > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsDuration() bool {
|
||||
return f&ValueDuration > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsTime() bool {
|
||||
return f&ValueTime > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsAny() bool {
|
||||
return f&ValueAny > 0
|
||||
}
|
||||
97
input/flag/flag.go
Normal file
97
input/flag/flag.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package flag
|
||||
|
||||
//go:generate stringer -type=Flag -linecomment
|
||||
|
||||
type Flag int
|
||||
|
||||
const (
|
||||
String Flag = 0 // string
|
||||
Required Flag = 1 << iota // required
|
||||
Array // array
|
||||
Int // int
|
||||
Int64 // int64
|
||||
Uint // uint
|
||||
Uint64 // uint64
|
||||
Float64 // float64
|
||||
Bool // bool
|
||||
Duration // duration
|
||||
Time // time
|
||||
Any // any
|
||||
)
|
||||
|
||||
func (f Flag) With(v Flag) Flag {
|
||||
return f | v
|
||||
}
|
||||
|
||||
func (f Flag) IsString() bool {
|
||||
return f|Required|Array^Required^Array == 0
|
||||
}
|
||||
|
||||
func (f Flag) IsRequired() bool {
|
||||
return f&Required > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsArray() bool {
|
||||
return f&Array > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsInt() bool {
|
||||
return f&Int > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsInt64() bool {
|
||||
return f&Int64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsUint() bool {
|
||||
return f&Uint > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsUint64() bool {
|
||||
return f&Uint64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsFloat64() bool {
|
||||
return f&Float64 > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsBool() bool {
|
||||
return f&Bool > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsDuration() bool {
|
||||
return f&Duration > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsTime() bool {
|
||||
return f&Time > 0
|
||||
}
|
||||
|
||||
func (f Flag) IsAny() bool {
|
||||
return f&Any > 0
|
||||
}
|
||||
|
||||
func (f Flag) Type() Flag {
|
||||
switch {
|
||||
case f.IsInt():
|
||||
return Int
|
||||
case f.IsInt64():
|
||||
return Int64
|
||||
case f.IsUint():
|
||||
return Uint
|
||||
case f.IsUint64():
|
||||
return Uint64
|
||||
case f.IsFloat64():
|
||||
return Float64
|
||||
case f.IsBool():
|
||||
return Bool
|
||||
case f.IsDuration():
|
||||
return Duration
|
||||
case f.IsTime():
|
||||
return Time
|
||||
case f.IsAny():
|
||||
return Any
|
||||
default:
|
||||
return String
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by "stringer -type=Flag -linecomment"; DO NOT EDIT.
|
||||
|
||||
package input
|
||||
package flag
|
||||
|
||||
import "strconv"
|
||||
|
||||
@@ -8,18 +8,18 @@ func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[ValueString-0]
|
||||
_ = x[ValueRequired-2]
|
||||
_ = x[ValueArray-4]
|
||||
_ = x[ValueInt-8]
|
||||
_ = x[ValueInt64-16]
|
||||
_ = x[ValueUint-32]
|
||||
_ = x[ValueUint64-64]
|
||||
_ = x[ValueFloat64-128]
|
||||
_ = x[ValueBool-256]
|
||||
_ = x[ValueDuration-512]
|
||||
_ = x[ValueTime-1024]
|
||||
_ = x[ValueAny-2048]
|
||||
_ = x[String-0]
|
||||
_ = x[Required-2]
|
||||
_ = x[Array-4]
|
||||
_ = x[Int-8]
|
||||
_ = x[Int64-16]
|
||||
_ = x[Uint-32]
|
||||
_ = x[Uint64-64]
|
||||
_ = x[Float64-128]
|
||||
_ = x[Bool-256]
|
||||
_ = x[Duration-512]
|
||||
_ = x[Time-1024]
|
||||
_ = x[Any-2048]
|
||||
}
|
||||
|
||||
const _Flag_name = "stringrequiredarrayintint64uintuint64float64booldurationtimeany"
|
||||
@@ -2,20 +2,22 @@ package input
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
)
|
||||
|
||||
type ReadInput interface {
|
||||
Bind(ctx context.Context, def *Definition) error
|
||||
|
||||
ReadOption(ctx context.Context, name string) (Value, error)
|
||||
SetOption(name string, value Value)
|
||||
ReadOption(ctx context.Context, name string) (value.Value, error)
|
||||
SetOption(name string, v value.Value)
|
||||
|
||||
ReadArgument(ctx context.Context, name string) (Value, error)
|
||||
SetArgument(name string, value Value)
|
||||
ReadArgument(ctx context.Context, name string) (value.Value, error)
|
||||
SetArgument(name string, v value.Value)
|
||||
}
|
||||
|
||||
type Input interface {
|
||||
Option(ctx context.Context, name string) Value
|
||||
Argument(ctx context.Context, name string) Value
|
||||
Option(ctx context.Context, name string) value.Value
|
||||
Argument(ctx context.Context, name string) value.Value
|
||||
ReadInput
|
||||
}
|
||||
|
||||
@@ -1,53 +1 @@
|
||||
package input
|
||||
|
||||
func NewOption(name, description string, opts ...func(*Option)) Option {
|
||||
o := Option{
|
||||
Name: name,
|
||||
Description: description,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&o)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
Name string
|
||||
Description string
|
||||
Short string
|
||||
Flag Flag
|
||||
Default Value
|
||||
Valid []func(Value) error
|
||||
}
|
||||
|
||||
func (o Option) HasShort() bool {
|
||||
return len(o.Short) == 1
|
||||
}
|
||||
|
||||
func (o Option) HasDefault() bool {
|
||||
return o.Default != nil
|
||||
}
|
||||
|
||||
func (o Option) IsBool() bool {
|
||||
return o.Flag.IsBool()
|
||||
}
|
||||
|
||||
func (o Option) IsArray() bool {
|
||||
return o.Flag.IsArray()
|
||||
}
|
||||
|
||||
func (o Option) IsRequired() bool {
|
||||
return o.Flag.IsRequired()
|
||||
}
|
||||
|
||||
func (o Option) Validate(v Value) error {
|
||||
for _, valid := range o.Valid {
|
||||
if err := valid(v); err != nil {
|
||||
return ErrorOption(o.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
package option
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input"
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
func Bool(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueBool))...)
|
||||
func Bool(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Bool))...)
|
||||
}
|
||||
|
||||
func Duration(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueDuration))...)
|
||||
func Duration(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Duration))...)
|
||||
}
|
||||
|
||||
func Float64(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueFloat64))...)
|
||||
func Float64(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Float64))...)
|
||||
}
|
||||
|
||||
func Int(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueInt))...)
|
||||
func Int(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Int))...)
|
||||
}
|
||||
|
||||
func Int64(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueInt64))...)
|
||||
func Int64(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Int64))...)
|
||||
}
|
||||
|
||||
func Time(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueTime))...)
|
||||
func Time(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Time))...)
|
||||
}
|
||||
|
||||
func Uint(name, description string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, description, append(opts, Value(input.ValueUint))...)
|
||||
func Uint(name, description string, opts ...func(*Option)) Option {
|
||||
return New(name, description, append(opts, Value(flag.Uint))...)
|
||||
}
|
||||
|
||||
func Uint64(name, descriontion string, opts ...func(*input.Option)) input.Option {
|
||||
return input.NewOption(name, descriontion, append(opts, Value(input.ValueUint64))...)
|
||||
func Uint64(name, descriontion string, opts ...func(*Option)) Option {
|
||||
return New(name, descriontion, append(opts, Value(flag.Uint64))...)
|
||||
}
|
||||
|
||||
@@ -1,44 +1,100 @@
|
||||
package option
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
)
|
||||
|
||||
func Required(o *input.Option) {
|
||||
o.Flag |= input.ValueRequired
|
||||
func Required(o *Option) {
|
||||
o.Flag |= flag.Required
|
||||
}
|
||||
|
||||
func Default(in interface{}) func(*input.Option) {
|
||||
return func(o *input.Option) {
|
||||
func Default(in interface{}) func(*Option) {
|
||||
return func(o *Option) {
|
||||
o.Default = value.New(in)
|
||||
}
|
||||
}
|
||||
|
||||
func Short(s string) func(*input.Option) {
|
||||
return func(o *input.Option) {
|
||||
func Short(s string) func(*Option) {
|
||||
return func(o *Option) {
|
||||
o.Short = s
|
||||
}
|
||||
}
|
||||
|
||||
func Array(o *input.Option) {
|
||||
o.Flag |= input.ValueArray
|
||||
func Array(o *Option) {
|
||||
o.Flag |= flag.Array
|
||||
}
|
||||
|
||||
func Value(flag input.Flag) func(*input.Option) {
|
||||
return func(o *input.Option) {
|
||||
func Value(flag flag.Flag) func(*Option) {
|
||||
return func(o *Option) {
|
||||
o.Flag |= flag
|
||||
}
|
||||
}
|
||||
|
||||
func Flag(in input.Flag) func(*input.Option) {
|
||||
return func(o *input.Option) {
|
||||
func Flag(in flag.Flag) func(*Option) {
|
||||
return func(o *Option) {
|
||||
o.Flag = in
|
||||
}
|
||||
}
|
||||
|
||||
func Valid(f ...func(input.Value) error) func(*input.Option) {
|
||||
return func(o *input.Option) {
|
||||
func Valid(f ...func(value.Value) error) func(*Option) {
|
||||
return func(o *Option) {
|
||||
o.Valid = f
|
||||
}
|
||||
}
|
||||
|
||||
func New(name, description string, opts ...func(*Option)) Option {
|
||||
o := Option{
|
||||
Name: name,
|
||||
Description: description,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&o)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
Name string
|
||||
Description string
|
||||
Short string
|
||||
Flag flag.Flag
|
||||
Default value.Value
|
||||
Valid []func(value.Value) error
|
||||
}
|
||||
|
||||
func (o Option) HasShort() bool {
|
||||
return len(o.Short) == 1
|
||||
}
|
||||
|
||||
func (o Option) HasDefault() bool {
|
||||
return o.Default != nil
|
||||
}
|
||||
|
||||
func (o Option) IsBool() bool {
|
||||
return o.Flag.IsBool()
|
||||
}
|
||||
|
||||
func (o Option) IsArray() bool {
|
||||
return o.Flag.IsArray()
|
||||
}
|
||||
|
||||
func (o Option) IsRequired() bool {
|
||||
return o.Flag.IsRequired()
|
||||
}
|
||||
|
||||
func (o Option) Validate(v value.Value) error {
|
||||
for _, valid := range o.Valid {
|
||||
if err := valid(v); err != nil {
|
||||
return Error(o.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Error(name string, err error) error {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package validator
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input"
|
||||
import "gitoa.ru/go-4devs/console/input/value"
|
||||
|
||||
func Enum(enum ...string) func(input.Value) error {
|
||||
return func(in input.Value) error {
|
||||
func Enum(enum ...string) func(value.Value) error {
|
||||
return func(in value.Value) error {
|
||||
v := in.String()
|
||||
for _, e := range enum {
|
||||
if e == v {
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
func TestEnum(t *testing.T) {
|
||||
@@ -1,32 +1,33 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
)
|
||||
|
||||
//nolint: gocyclo
|
||||
func NotBlank(flag input.Flag) func(input.Value) error {
|
||||
return func(in input.Value) error {
|
||||
func NotBlank(f flag.Flag) func(value.Value) error {
|
||||
return func(in value.Value) error {
|
||||
switch {
|
||||
case flag.IsAny() && in.Any() != nil:
|
||||
case f.IsAny() && in.Any() != nil:
|
||||
return nil
|
||||
case flag.IsArray():
|
||||
return arrayNotBlank(flag, in)
|
||||
case flag.IsInt() && in.Int() != 0:
|
||||
case f.IsArray():
|
||||
return arrayNotBlank(f, in)
|
||||
case f.IsInt() && in.Int() != 0:
|
||||
return nil
|
||||
case flag.IsInt64() && in.Int64() != 0:
|
||||
case f.IsInt64() && in.Int64() != 0:
|
||||
return nil
|
||||
case flag.IsUint() && in.Uint() != 0:
|
||||
case f.IsUint() && in.Uint() != 0:
|
||||
return nil
|
||||
case flag.IsUint64() && in.Uint64() != 0:
|
||||
case f.IsUint64() && in.Uint64() != 0:
|
||||
return nil
|
||||
case flag.IsFloat64() && in.Float64() != 0:
|
||||
case f.IsFloat64() && in.Float64() != 0:
|
||||
return nil
|
||||
case flag.IsDuration() && in.Duration() != 0:
|
||||
case f.IsDuration() && in.Duration() != 0:
|
||||
return nil
|
||||
case flag.IsTime() && !in.Time().IsZero():
|
||||
case f.IsTime() && !in.Time().IsZero():
|
||||
return nil
|
||||
case flag.IsString() && len(in.String()) > 0:
|
||||
case f.IsString() && len(in.String()) > 0:
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -35,9 +36,9 @@ func NotBlank(flag input.Flag) func(input.Value) error {
|
||||
}
|
||||
|
||||
//nolint: gocyclo,gocognit
|
||||
func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
func arrayNotBlank(f flag.Flag, in value.Value) error {
|
||||
switch {
|
||||
case flag.IsInt() && len(in.Ints()) > 0:
|
||||
case f.IsInt() && len(in.Ints()) > 0:
|
||||
for _, i := range in.Ints() {
|
||||
if i == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -45,7 +46,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsInt64() && len(in.Int64s()) > 0:
|
||||
case f.IsInt64() && len(in.Int64s()) > 0:
|
||||
for _, i := range in.Int64s() {
|
||||
if i == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -53,7 +54,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsUint() && len(in.Uints()) > 0:
|
||||
case f.IsUint() && len(in.Uints()) > 0:
|
||||
for _, u := range in.Uints() {
|
||||
if u == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -61,7 +62,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsUint64() && len(in.Uint64s()) > 0:
|
||||
case f.IsUint64() && len(in.Uint64s()) > 0:
|
||||
for _, u := range in.Uint64s() {
|
||||
if u == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -69,7 +70,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsFloat64() && len(in.Float64s()) > 0:
|
||||
case f.IsFloat64() && len(in.Float64s()) > 0:
|
||||
for _, f := range in.Float64s() {
|
||||
if f == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -77,9 +78,9 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsBool() && len(in.Bools()) > 0:
|
||||
case f.IsBool() && len(in.Bools()) > 0:
|
||||
return nil
|
||||
case flag.IsDuration() && len(in.Durations()) > 0:
|
||||
case f.IsDuration() && len(in.Durations()) > 0:
|
||||
for _, d := range in.Durations() {
|
||||
if d == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -87,7 +88,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsTime() && len(in.Times()) > 0:
|
||||
case f.IsTime() && len(in.Times()) > 0:
|
||||
for _, t := range in.Times() {
|
||||
if t.IsZero() {
|
||||
return ErrNotBlank
|
||||
@@ -95,7 +96,7 @@ func arrayNotBlank(flag input.Flag, in input.Value) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
case flag.IsString() && len(in.Strings()) > 0:
|
||||
case f.IsString() && len(in.Strings()) > 0:
|
||||
for _, st := range in.Strings() {
|
||||
if len(st) == 0 {
|
||||
return ErrNotBlank
|
||||
@@ -5,90 +5,90 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
func TestNotBlank(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
flag input.Flag
|
||||
value input.Value
|
||||
empty input.Value
|
||||
flag flag.Flag
|
||||
value value.Value
|
||||
empty value.Value
|
||||
}{
|
||||
"any": {flag: input.ValueAny, value: value.New(float32(1))},
|
||||
"any": {flag: flag.Any, value: value.New(float32(1))},
|
||||
"array int": {
|
||||
flag: input.ValueInt | input.ValueArray,
|
||||
flag: flag.Int | flag.Array,
|
||||
value: value.New([]int{1}),
|
||||
empty: value.New([]int{10, 20, 0}),
|
||||
},
|
||||
"array int64": {
|
||||
flag: input.ValueInt64 | input.ValueArray,
|
||||
flag: flag.Int64 | flag.Array,
|
||||
value: value.New([]int64{1}),
|
||||
empty: value.New([]int64{0}),
|
||||
},
|
||||
"array uint": {
|
||||
flag: input.ValueUint | input.ValueArray,
|
||||
flag: flag.Uint | flag.Array,
|
||||
value: value.New([]uint{1}),
|
||||
empty: value.New([]uint{1, 0}),
|
||||
},
|
||||
"array uint64": {
|
||||
flag: input.ValueUint64 | input.ValueArray,
|
||||
flag: flag.Uint64 | flag.Array,
|
||||
value: value.New([]uint64{1}),
|
||||
empty: value.New([]uint64{0}),
|
||||
},
|
||||
"array float64": {
|
||||
flag: input.ValueFloat64 | input.ValueArray,
|
||||
flag: flag.Float64 | flag.Array,
|
||||
value: value.New([]float64{0.2}),
|
||||
empty: value.New([]float64{0}),
|
||||
},
|
||||
"array bool": {
|
||||
flag: input.ValueBool | input.ValueArray,
|
||||
flag: flag.Bool | flag.Array,
|
||||
value: value.New([]bool{true, false}),
|
||||
empty: value.New([]bool{}),
|
||||
},
|
||||
"array duration": {
|
||||
flag: input.ValueDuration | input.ValueArray,
|
||||
flag: flag.Duration | flag.Array,
|
||||
value: value.New([]time.Duration{time.Second}),
|
||||
empty: value.New([]time.Duration{time.Second, 0}),
|
||||
},
|
||||
"array time": {
|
||||
flag: input.ValueTime | input.ValueArray,
|
||||
flag: flag.Time | flag.Array,
|
||||
value: value.New([]time.Time{time.Now()}),
|
||||
empty: value.New([]time.Time{{}, time.Now()}),
|
||||
},
|
||||
"array string": {
|
||||
flag: input.ValueArray,
|
||||
flag: flag.Array,
|
||||
value: value.New([]string{"value"}),
|
||||
empty: value.New([]string{""}),
|
||||
},
|
||||
"int": {
|
||||
flag: input.ValueInt,
|
||||
flag: flag.Int,
|
||||
value: value.New(int(1)),
|
||||
},
|
||||
"int64": {
|
||||
flag: input.ValueInt64,
|
||||
flag: flag.Int64,
|
||||
value: value.New(int64(2)),
|
||||
},
|
||||
"uint": {
|
||||
flag: input.ValueUint,
|
||||
flag: flag.Uint,
|
||||
value: value.New(uint(1)),
|
||||
empty: value.New([]uint{1}),
|
||||
},
|
||||
"uint64": {
|
||||
flag: input.ValueUint64,
|
||||
flag: flag.Uint64,
|
||||
value: value.New(uint64(10)),
|
||||
},
|
||||
"float64": {
|
||||
flag: input.ValueFloat64,
|
||||
flag: flag.Float64,
|
||||
value: value.New(float64(.00001)),
|
||||
},
|
||||
"duration": {
|
||||
flag: input.ValueDuration,
|
||||
flag: flag.Duration,
|
||||
value: value.New(time.Minute),
|
||||
empty: value.New("same string"),
|
||||
},
|
||||
"time": {flag: input.ValueTime, value: value.New(time.Now())},
|
||||
"time": {flag: flag.Time, value: value.New(time.Now())},
|
||||
"string": {value: value.New("string"), empty: value.New("")},
|
||||
}
|
||||
|
||||
15
input/validator/valid.go
Normal file
15
input/validator/valid.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package validator
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input/value"
|
||||
|
||||
func Valid(v ...func(value.Value) error) func(value.Value) error {
|
||||
return func(in value.Value) error {
|
||||
for _, valid := range v {
|
||||
if err := valid(in); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/input/value"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
func TestValid(t *testing.T) {
|
||||
@@ -14,7 +14,7 @@ func TestValid(t *testing.T) {
|
||||
invalidValue := value.New([]string{"one"})
|
||||
|
||||
valid := validator.Valid(
|
||||
validator.NotBlank(input.ValueString),
|
||||
validator.NotBlank(flag.String),
|
||||
validator.Enum("one", "two"),
|
||||
)
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package input
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Value interface {
|
||||
String() string
|
||||
Int() int
|
||||
Int64() int64
|
||||
Uint() uint
|
||||
Uint64() uint64
|
||||
Float64() float64
|
||||
Bool() bool
|
||||
Duration() time.Duration
|
||||
Time() time.Time
|
||||
Any() interface{}
|
||||
|
||||
Strings() []string
|
||||
Ints() []int
|
||||
Int64s() []int64
|
||||
Uints() []uint
|
||||
Uint64s() []uint64
|
||||
Float64s() []float64
|
||||
Bools() []bool
|
||||
Durations() []time.Duration
|
||||
Times() []time.Time
|
||||
}
|
||||
|
||||
type AppendValue interface {
|
||||
Value
|
||||
Append(string) error
|
||||
}
|
||||
|
||||
func Type(flag Flag) Flag {
|
||||
switch {
|
||||
case (flag & ValueInt) > 0:
|
||||
return ValueInt
|
||||
case (flag & ValueInt64) > 0:
|
||||
return ValueInt64
|
||||
case (flag & ValueUint) > 0:
|
||||
return ValueUint
|
||||
case (flag & ValueUint64) > 0:
|
||||
return ValueUint64
|
||||
case (flag & ValueFloat64) > 0:
|
||||
return ValueFloat64
|
||||
case (flag & ValueBool) > 0:
|
||||
return ValueBool
|
||||
case (flag & ValueDuration) > 0:
|
||||
return ValueDuration
|
||||
case (flag & ValueTime) > 0:
|
||||
return ValueTime
|
||||
case (flag & ValueAny) > 0:
|
||||
return ValueAny
|
||||
default:
|
||||
return ValueString
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package value
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input"
|
||||
import "gitoa.ru/go-4devs/console/input/flag"
|
||||
|
||||
type Any struct {
|
||||
Empty
|
||||
Val []interface{}
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (a *Any) Any() interface{} {
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Bool struct {
|
||||
Empty
|
||||
Val []bool
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (b *Bool) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (b *Bool) Bools() []bool {
|
||||
}
|
||||
|
||||
func (b *Bool) Any() interface{} {
|
||||
if b.Flag&input.ValueArray > 0 {
|
||||
if b.Flag.IsArray() {
|
||||
return b.Bools()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Duration struct {
|
||||
Empty
|
||||
Val []time.Duration
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (d *Duration) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (d *Duration) Durations() []time.Duration {
|
||||
}
|
||||
|
||||
func (d *Duration) Any() interface{} {
|
||||
if d.Flag&input.ValueArray > 0 {
|
||||
if d.Flag.IsArray() {
|
||||
return d.Durations()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package value
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
)
|
||||
|
||||
type Empty struct{}
|
||||
|
||||
func (e *Empty) Append(string) error {
|
||||
return fmt.Errorf("%w: in empty value", input.ErrInvalidName)
|
||||
return ErrAppendEmpty
|
||||
}
|
||||
|
||||
func (e *Empty) String() string {
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Float64 struct {
|
||||
Empty
|
||||
Val []float64
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (f *Float64) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (f *Float64) Float64s() []float64 {
|
||||
}
|
||||
|
||||
func (f *Float64) Any() interface{} {
|
||||
if f.Flag&input.ValueFloat64 > 0 {
|
||||
if f.Flag.IsArray() {
|
||||
return f.Float64s()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Int struct {
|
||||
Empty
|
||||
Val []int
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (i *Int) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (i *Int) Ints() []int {
|
||||
}
|
||||
|
||||
func (i *Int) Any() interface{} {
|
||||
if i.Flag&input.ValueArray > 0 {
|
||||
if i.Flag.IsArray() {
|
||||
return i.Ints()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Int64 struct {
|
||||
Empty
|
||||
Val []int64
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (i *Int64) Int64() int64 {
|
||||
@@ -25,7 +25,7 @@ func (i *Int64) Int64s() []int64 {
|
||||
}
|
||||
|
||||
func (i *Int64) Any() interface{} {
|
||||
if i.Flag&input.ValueArray > 0 {
|
||||
if i.Flag.IsArray() {
|
||||
return i.Int64s()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package value
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var _ input.AppendValue = (*Read)(nil)
|
||||
var _ AppendValue = (*Read)(nil)
|
||||
|
||||
var (
|
||||
ErrAppendRead = errors.New("invalid append data to read value")
|
||||
ErrAppendEmpty = errors.New("invalid apped data to empty value")
|
||||
)
|
||||
|
||||
type Read struct {
|
||||
input.Value
|
||||
Value
|
||||
}
|
||||
|
||||
func (r *Read) Append(string) error {
|
||||
return fmt.Errorf("%w: read value", input.ErrInvalidName)
|
||||
return ErrAppendRead
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package value
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input"
|
||||
import "gitoa.ru/go-4devs/console/input/flag"
|
||||
|
||||
type String struct {
|
||||
Empty
|
||||
Val []string
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (s *String) Append(in string) error {
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Time struct {
|
||||
Empty
|
||||
Val []time.Time
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (t *Time) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (t *Time) Times() []time.Time {
|
||||
}
|
||||
|
||||
func (t *Time) Amy() interface{} {
|
||||
if t.Flag&input.ValueArray > 0 {
|
||||
if t.Flag.IsArray() {
|
||||
return t.Times()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Uint struct {
|
||||
Empty
|
||||
Val []uint
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (u *Uint) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (u *Uint) Uints() []uint {
|
||||
}
|
||||
|
||||
func (u *Uint) Any() interface{} {
|
||||
if u.Flag&input.ValueArray > 0 {
|
||||
if u.Flag.IsArray() {
|
||||
return u.Uints()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ package value
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Uint64 struct {
|
||||
Empty
|
||||
Val []uint64
|
||||
Flag input.Flag
|
||||
Flag flag.Flag
|
||||
}
|
||||
|
||||
func (u *Uint64) Append(in string) error {
|
||||
@@ -36,7 +36,7 @@ func (u *Uint64) Uint64s() []uint64 {
|
||||
}
|
||||
|
||||
func (u *Uint64) Any() interface{} {
|
||||
if u.Flag&input.ValueArray > 0 {
|
||||
if u.Flag.IsArray() {
|
||||
return u.Uint64s()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,81 +3,109 @@ package value
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/flag"
|
||||
)
|
||||
|
||||
type Value interface {
|
||||
String() string
|
||||
Int() int
|
||||
Int64() int64
|
||||
Uint() uint
|
||||
Uint64() uint64
|
||||
Float64() float64
|
||||
Bool() bool
|
||||
Duration() time.Duration
|
||||
Time() time.Time
|
||||
Any() interface{}
|
||||
|
||||
Strings() []string
|
||||
Ints() []int
|
||||
Int64s() []int64
|
||||
Uints() []uint
|
||||
Uint64s() []uint64
|
||||
Float64s() []float64
|
||||
Bools() []bool
|
||||
Durations() []time.Duration
|
||||
Times() []time.Time
|
||||
}
|
||||
|
||||
type AppendValue interface {
|
||||
Value
|
||||
Append(string) error
|
||||
}
|
||||
|
||||
//nolint: gocyclo
|
||||
func New(v interface{}) input.Value {
|
||||
func New(v interface{}) Value {
|
||||
switch val := v.(type) {
|
||||
case string:
|
||||
return &String{Val: []string{val}, Flag: input.ValueString}
|
||||
return &String{Val: []string{val}, Flag: flag.String}
|
||||
case int:
|
||||
return &Int{Val: []int{val}, Flag: input.ValueInt}
|
||||
return &Int{Val: []int{val}, Flag: flag.Int}
|
||||
case int64:
|
||||
return &Int64{Val: []int64{val}, Flag: input.ValueInt64}
|
||||
return &Int64{Val: []int64{val}, Flag: flag.Int64}
|
||||
case uint:
|
||||
return &Uint{Val: []uint{val}, Flag: input.ValueUint}
|
||||
return &Uint{Val: []uint{val}, Flag: flag.Uint}
|
||||
case uint64:
|
||||
return &Uint64{Val: []uint64{val}, Flag: input.ValueUint64}
|
||||
return &Uint64{Val: []uint64{val}, Flag: flag.Uint64}
|
||||
case float64:
|
||||
return &Float64{Val: []float64{val}, Flag: input.ValueFloat64}
|
||||
return &Float64{Val: []float64{val}, Flag: flag.Float64}
|
||||
case bool:
|
||||
return &Bool{Val: []bool{val}, Flag: input.ValueBool}
|
||||
return &Bool{Val: []bool{val}, Flag: flag.Bool}
|
||||
case time.Duration:
|
||||
return &Duration{Val: []time.Duration{val}, Flag: input.ValueDuration}
|
||||
return &Duration{Val: []time.Duration{val}, Flag: flag.Duration}
|
||||
case time.Time:
|
||||
return &Time{Val: []time.Time{val}, Flag: input.ValueTime}
|
||||
return &Time{Val: []time.Time{val}, Flag: flag.Time}
|
||||
case []int64:
|
||||
return &Int64{Val: val, Flag: input.ValueInt64 | input.ValueArray}
|
||||
return &Int64{Val: val, Flag: flag.Int64 | flag.Array}
|
||||
case []uint:
|
||||
return &Uint{Val: val, Flag: input.ValueUint | input.ValueArray}
|
||||
return &Uint{Val: val, Flag: flag.Uint | flag.Array}
|
||||
case []uint64:
|
||||
return &Uint64{Val: val, Flag: input.ValueUint64 | input.ValueArray}
|
||||
return &Uint64{Val: val, Flag: flag.Uint64 | flag.Array}
|
||||
case []float64:
|
||||
return &Float64{Val: val, Flag: input.ValueFloat64 | input.ValueArray}
|
||||
return &Float64{Val: val, Flag: flag.Float64 | flag.Array}
|
||||
case []bool:
|
||||
return &Bool{Val: val, Flag: input.ValueBool | input.ValueArray}
|
||||
return &Bool{Val: val, Flag: flag.Bool | flag.Array}
|
||||
case []time.Duration:
|
||||
return &Duration{Val: val, Flag: input.ValueDuration | input.ValueArray}
|
||||
return &Duration{Val: val, Flag: flag.Duration | flag.Array}
|
||||
case []time.Time:
|
||||
return &Time{Val: val, Flag: input.ValueTime | input.ValueArray}
|
||||
return &Time{Val: val, Flag: flag.Time | flag.Array}
|
||||
case []string:
|
||||
return &String{Val: val, Flag: input.ValueString | input.ValueArray}
|
||||
return &String{Val: val, Flag: flag.String | flag.Array}
|
||||
case []int:
|
||||
return &Int{Val: val, Flag: input.ValueInt | input.ValueArray}
|
||||
return &Int{Val: val, Flag: flag.Int | flag.Array}
|
||||
case []interface{}:
|
||||
return &Any{Val: val, Flag: input.ValueAny | input.ValueArray}
|
||||
case input.Value:
|
||||
return &Any{Val: val, Flag: flag.Any | flag.Array}
|
||||
case Value:
|
||||
return val
|
||||
default:
|
||||
if v != nil {
|
||||
return &Any{Val: []interface{}{v}, Flag: input.ValueAny}
|
||||
return &Any{Val: []interface{}{v}, Flag: flag.Any}
|
||||
}
|
||||
|
||||
return &Empty{}
|
||||
}
|
||||
}
|
||||
|
||||
func ByFlag(flag input.Flag) input.AppendValue {
|
||||
func ByFlag(f flag.Flag) AppendValue {
|
||||
switch {
|
||||
case flag.IsInt():
|
||||
return &Int{Flag: flag | input.ValueInt}
|
||||
case flag.IsInt64():
|
||||
return &Int64{Flag: flag | input.ValueInt64}
|
||||
case flag.IsUint():
|
||||
return &Uint{Flag: flag | input.ValueUint}
|
||||
case flag.IsUint64():
|
||||
return &Uint64{Flag: flag | input.ValueUint64}
|
||||
case flag.IsFloat64():
|
||||
return &Float64{Flag: flag | input.ValueFloat64}
|
||||
case flag.IsBool():
|
||||
return &Bool{Flag: flag | input.ValueBool}
|
||||
case flag.IsDuration():
|
||||
return &Duration{Flag: flag | input.ValueDuration}
|
||||
case flag.IsTime():
|
||||
return &Time{Flag: flag | input.ValueTime}
|
||||
case flag.IsAny():
|
||||
return &Any{Flag: flag | input.ValueAny}
|
||||
case f.IsInt():
|
||||
return &Int{Flag: f | flag.Int}
|
||||
case f.IsInt64():
|
||||
return &Int64{Flag: f | flag.Int64}
|
||||
case f.IsUint():
|
||||
return &Uint{Flag: f | flag.Uint}
|
||||
case f.IsUint64():
|
||||
return &Uint64{Flag: f | flag.Uint64}
|
||||
case f.IsFloat64():
|
||||
return &Float64{Flag: f | flag.Float64}
|
||||
case f.IsBool():
|
||||
return &Bool{Flag: f | flag.Bool}
|
||||
case f.IsDuration():
|
||||
return &Duration{Flag: f | flag.Duration}
|
||||
case f.IsTime():
|
||||
return &Time{Flag: f | flag.Time}
|
||||
case f.IsAny():
|
||||
return &Any{Flag: f | flag.Any}
|
||||
default:
|
||||
return &String{}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ type Input struct {
|
||||
input.ReadInput
|
||||
}
|
||||
|
||||
func (i *Input) Option(ctx context.Context, name string) input.Value {
|
||||
func (i *Input) Option(ctx context.Context, name string) value.Value {
|
||||
if v, err := i.ReadOption(ctx, name); err == nil {
|
||||
return v
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func (i *Input) Option(ctx context.Context, name string) input.Value {
|
||||
return &value.Empty{}
|
||||
}
|
||||
|
||||
func (i *Input) Argument(ctx context.Context, name string) input.Value {
|
||||
func (i *Input) Argument(ctx context.Context, name string) value.Value {
|
||||
if v, err := i.ReadArgument(ctx, name); err == nil {
|
||||
return v
|
||||
}
|
||||
@@ -40,10 +40,6 @@ func (i *Input) Bind(ctx context.Context, def *input.Definition) error {
|
||||
return i.bindOptions(ctx, def)
|
||||
}
|
||||
|
||||
func (i *Input) build(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Input) bindOptions(ctx context.Context, def *input.Definition) error {
|
||||
for _, name := range def.Options() {
|
||||
opt, err := def.Option(name)
|
||||
|
||||
7
list.go
7
list.go
@@ -7,9 +7,10 @@ import (
|
||||
|
||||
"gitoa.ru/go-4devs/console/descriptor"
|
||||
"gitoa.ru/go-4devs/console/input"
|
||||
"gitoa.ru/go-4devs/console/input/argument"
|
||||
"gitoa.ru/go-4devs/console/input/option"
|
||||
"gitoa.ru/go-4devs/console/input/validator"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/validator"
|
||||
)
|
||||
|
||||
const defaultLenNamespace = 2
|
||||
@@ -92,10 +93,10 @@ You can also output the information in other formats by using the <comment>--for
|
||||
formats := descriptor.Descriptors()
|
||||
config.
|
||||
SetArguments(
|
||||
input.NewArgument("namespace", "The namespace name"),
|
||||
argument.New("namespace", "The namespace name"),
|
||||
).
|
||||
SetOptions(
|
||||
input.NewOption(helpOptFormat, fmt.Sprintf("The output format (%s)", strings.Join(formats, ", ")),
|
||||
option.New(helpOptFormat, fmt.Sprintf("The output format (%s)", strings.Join(formats, ", ")),
|
||||
option.Required,
|
||||
option.Default(formats[0]),
|
||||
option.Valid(
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package validator
|
||||
|
||||
import "gitoa.ru/go-4devs/console/input"
|
||||
|
||||
func Valid(v ...func(input.Value) error) func(input.Value) error {
|
||||
return func(in input.Value) error {
|
||||
for _, valid := range v {
|
||||
if err := valid(in); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user