Browse Source
Co-authored-by: andrey1s <andrey@4devs.pro> Reviewed-on: https://gitoa.ru/go-4devs/console/pulls/1 Co-authored-by: andrey <andrey@4devs.io> Co-committed-by: andrey <andrey@4devs.io>pull/2/head v0.1.0
andrey
2 years ago
74 changed files with 2532 additions and 883 deletions
@ -1,3 +1,9 @@ |
|||
module gitoa.ru/go-4devs/console |
|||
|
|||
go 1.15 |
|||
|
|||
require ( |
|||
github.com/kr/pretty v0.1.0 // indirect |
|||
github.com/stretchr/testify v1.8.0 |
|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect |
|||
) |
|||
|
@ -0,0 +1,21 @@ |
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
|||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= |
|||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
|||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
|||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= |
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
|||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= |
|||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
|||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= |
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= |
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= |
|||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
|||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
|||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
@ -1,54 +1,58 @@ |
|||
package argument |
|||
|
|||
import ( |
|||
"gitoa.ru/go-4devs/console/input/errs" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
"gitoa.ru/go-4devs/console/input/variable" |
|||
) |
|||
|
|||
func New(name, description string, opts ...func(*Argument)) Argument { |
|||
a := Argument{ |
|||
Name: name, |
|||
Description: description, |
|||
func Default(in interface{}) variable.Option { |
|||
return variable.Default(value.New(in)) |
|||
} |
|||
|
|||
for _, opt := range opts { |
|||
opt(&a) |
|||
func Required(v *variable.Variable) { |
|||
variable.Required(v) |
|||
} |
|||
|
|||
return a |
|||
func Array(v *variable.Variable) { |
|||
variable.Array(v) |
|||
} |
|||
|
|||
type Argument struct { |
|||
Name string |
|||
Description string |
|||
Default value.Value |
|||
Flag flag.Flag |
|||
Valid []func(value.Value) error |
|||
func String(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.String(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func (a Argument) HasDefault() bool { |
|||
return a.Default != nil |
|||
func Bool(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Bool(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func (a Argument) IsBool() bool { |
|||
return a.Flag.IsBool() |
|||
func Duration(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Duration(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func (a Argument) IsRequired() bool { |
|||
return a.Flag.IsRequired() |
|||
func Float64(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Float64(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func (a Argument) IsArray() bool { |
|||
return a.Flag.IsArray() |
|||
func Int(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Int(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func (a Argument) Validate(v value.Value) error { |
|||
for _, valid := range a.Valid { |
|||
if err := valid(v); err != nil { |
|||
return errs.Argument(a.Name, err) |
|||
func Int64(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Int64(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func Time(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Time(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func Uint(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Uint(name, description, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
func Uint64(name, descriontion string, opts ...variable.Option) variable.Variable { |
|||
return variable.Uint64(name, descriontion, append(opts, variable.ArgArgument)...) |
|||
} |
|||
|
|||
return nil |
|||
func Err(name string, err error) variable.Error { |
|||
return variable.Err(name, variable.TypeArgument, err) |
|||
} |
|||
|
@ -1,26 +0,0 @@ |
|||
package argument |
|||
|
|||
import ( |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
) |
|||
|
|||
func Required(a *Argument) { |
|||
a.Flag |= flag.Required |
|||
} |
|||
|
|||
func Default(v interface{}) func(*Argument) { |
|||
return func(a *Argument) { |
|||
a.Default = value.New(v) |
|||
} |
|||
} |
|||
|
|||
func Flag(flag flag.Flag) func(*Argument) { |
|||
return func(a *Argument) { |
|||
a.Flag = flag |
|||
} |
|||
} |
|||
|
|||
func Array(a *Argument) { |
|||
a.Flag |= flag.Array |
|||
} |
@ -1,37 +0,0 @@ |
|||
package option |
|||
|
|||
import ( |
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
) |
|||
|
|||
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(*Option)) Option { |
|||
return New(name, description, append(opts, Value(flag.Duration))...) |
|||
} |
|||
|
|||
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(*Option)) Option { |
|||
return New(name, description, append(opts, Value(flag.Int))...) |
|||
} |
|||
|
|||
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(*Option)) Option { |
|||
return New(name, description, append(opts, Value(flag.Time))...) |
|||
} |
|||
|
|||
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(*Option)) Option { |
|||
return New(name, descriontion, append(opts, Value(flag.Uint64))...) |
|||
} |
@ -1,97 +1,68 @@ |
|||
package option |
|||
|
|||
import ( |
|||
"gitoa.ru/go-4devs/console/input/errs" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
"gitoa.ru/go-4devs/console/input/variable" |
|||
) |
|||
|
|||
func Required(o *Option) { |
|||
o.Flag |= flag.Required |
|||
} |
|||
|
|||
func Default(in interface{}) func(*Option) { |
|||
return func(o *Option) { |
|||
o.Default = value.New(in) |
|||
func Short(in rune) variable.Option { |
|||
return func(v *variable.Variable) { |
|||
v.Alias = string(in) |
|||
} |
|||
} |
|||
|
|||
func Short(s string) func(*Option) { |
|||
return func(o *Option) { |
|||
o.Short = s |
|||
} |
|||
func Default(in interface{}) variable.Option { |
|||
return variable.Default(value.New(in)) |
|||
} |
|||
|
|||
func Array(o *Option) { |
|||
o.Flag |= flag.Array |
|||
func Required(v *variable.Variable) { |
|||
variable.Required(v) |
|||
} |
|||
|
|||
func Value(flag flag.Flag) func(*Option) { |
|||
return func(o *Option) { |
|||
o.Flag |= flag |
|||
} |
|||
func Valid(f ...func(value.Value) error) variable.Option { |
|||
return variable.Valid(f...) |
|||
} |
|||
|
|||
func Flag(in flag.Flag) func(*Option) { |
|||
return func(o *Option) { |
|||
o.Flag = in |
|||
} |
|||
func Array(v *variable.Variable) { |
|||
variable.Array(v) |
|||
} |
|||
|
|||
func Valid(f ...func(value.Value) error) func(*Option) { |
|||
return func(o *Option) { |
|||
o.Valid = f |
|||
} |
|||
func String(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.String(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
func New(name, description string, opts ...func(*Option)) Option { |
|||
o := Option{ |
|||
Name: name, |
|||
Description: description, |
|||
func Bool(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Bool(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
for _, opt := range opts { |
|||
opt(&o) |
|||
func Duration(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Duration(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
return o |
|||
func Float64(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Float64(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
type Option struct { |
|||
Name string |
|||
Description string |
|||
Short string |
|||
Flag flag.Flag |
|||
Default value.Value |
|||
Valid []func(value.Value) error |
|||
func Int(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Int(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
func (o Option) HasShort() bool { |
|||
return len(o.Short) == 1 |
|||
func Int64(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Int64(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
func (o Option) HasDefault() bool { |
|||
return o.Default != nil |
|||
func Time(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Time(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
func (o Option) IsBool() bool { |
|||
return o.Flag.IsBool() |
|||
func Uint(name, description string, opts ...variable.Option) variable.Variable { |
|||
return variable.Uint(name, description, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
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 errs.Option(o.Name, err) |
|||
} |
|||
func Uint64(name, descriontion string, opts ...variable.Option) variable.Variable { |
|||
return variable.Uint64(name, descriontion, append(opts, variable.ArgOption)...) |
|||
} |
|||
|
|||
return nil |
|||
func Err(name string, err error) variable.Error { |
|||
return variable.Err(name, variable.TypeOption, err) |
|||
} |
|||
|
@ -1,21 +1,137 @@ |
|||
package value |
|||
|
|||
import "gitoa.ru/go-4devs/console/input/value/flag" |
|||
import ( |
|||
"encoding/json" |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
var _ Value = NewAny(nil) |
|||
|
|||
//nolint:gochecknoglobals
|
|||
var ( |
|||
emptyValue = NewAny(nil) |
|||
) |
|||
|
|||
func Empty() Value { |
|||
return emptyValue |
|||
} |
|||
|
|||
func IsEmpty(v Value) bool { |
|||
return v == nil || v == emptyValue |
|||
} |
|||
|
|||
func NewAny(in interface{}) Value { |
|||
return Read{Any{v: in}} |
|||
} |
|||
|
|||
type Any struct { |
|||
empty |
|||
Val []interface{} |
|||
Flag flag.Flag |
|||
v interface{} |
|||
} |
|||
|
|||
func (a Any) Any() interface{} { |
|||
return a.v |
|||
} |
|||
|
|||
func (a *Any) Any() interface{} { |
|||
if a.Flag.IsArray() { |
|||
return a.Val |
|||
func (a Any) Unmarshal(val interface{}) error { |
|||
out, err := a.ParseString() |
|||
if err != nil { |
|||
return fmt.Errorf("any parse string:%w", err) |
|||
} |
|||
|
|||
if len(a.Val) > 0 { |
|||
return a.Val[0] |
|||
uerr := json.Unmarshal([]byte(out), val) |
|||
if uerr != nil { |
|||
return fmt.Errorf("any unmarshal: %w", uerr) |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (a Any) ParseString() (string, error) { |
|||
if a.v == nil { |
|||
return "", nil |
|||
} |
|||
|
|||
bout, err := json.Marshal(a.v) |
|||
if err != nil { |
|||
return "", fmt.Errorf("any string:%w", err) |
|||
} |
|||
|
|||
return string(bout), err |
|||
} |
|||
|
|||
func (a Any) ParseInt() (int, error) { |
|||
out, ok := a.v.(int) |
|||
if !ok { |
|||
return 0, a.wrongType("int") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseInt64() (int64, error) { |
|||
out, ok := a.v.(int64) |
|||
if !ok { |
|||
return 0, a.wrongType("int64") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseUint() (uint, error) { |
|||
out, ok := a.v.(uint) |
|||
if !ok { |
|||
return 0, a.wrongType("uint") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseUint64() (uint64, error) { |
|||
out, ok := a.v.(uint64) |
|||
if !ok { |
|||
return 0, a.wrongType("uint64") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseFloat64() (float64, error) { |
|||
out, ok := a.v.(float64) |
|||
if !ok { |
|||
return 0, a.wrongType("float64") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseBool() (bool, error) { |
|||
out, ok := a.v.(bool) |
|||
if !ok { |
|||
return false, a.wrongType("bool") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseDuration() (time.Duration, error) { |
|||
out, ok := a.v.(time.Duration) |
|||
if !ok { |
|||
return 0, a.wrongType("time.Duration") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) ParseTime() (time.Time, error) { |
|||
out, ok := a.v.(time.Time) |
|||
if !ok { |
|||
return time.Time{}, a.wrongType("time.Time") |
|||
} |
|||
|
|||
return out, nil |
|||
} |
|||
|
|||
func (a Any) wrongType(ex String) error { |
|||
return fmt.Errorf("%w any: got: %T expect: %s", ErrWrongType, a.v, ex) |
|||
} |
|||
|
@ -1,44 +1,148 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"strconv" |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Bool(false) |
|||
_ SliceValue = Bools{} |
|||
) |
|||
|
|||
type Bool struct { |
|||
empty |
|||
Val []bool |
|||
Flag flag.Flag |
|||
func NewBools(in []bool) Slice { |
|||
return Slice{SliceValue: Bools(in)} |
|||
} |
|||
|
|||
type Bools []bool |
|||
|
|||
func (b Bools) Any() interface{} { |
|||
return b.Bools() |
|||
} |
|||
|
|||
func (b Bools) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*[]bool) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect: *[]bool got: %T", ErrWrongType, val) |
|||
} |
|||
|
|||
func (b *Bool) Append(in string) error { |
|||
v, err := strconv.ParseBool(in) |
|||
if err != nil { |
|||
return err |
|||
*v = b |
|||
|
|||
return nil |
|||
} |
|||
|
|||
b.Val = append(b.Val, v) |
|||
func (b Bools) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (b Bools) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (b *Bool) Bool() bool { |
|||
if !b.Flag.IsArray() && len(b.Val) == 1 { |
|||
return b.Val[0] |
|||
func (b Bools) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
return false |
|||
func (b Bools) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (b *Bool) Bools() []bool { |
|||
return b.Val |
|||
func (b Bools) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (b *Bool) Any() interface{} { |
|||
if b.Flag.IsArray() { |
|||
return b.Bools() |
|||
func (b Bools) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (b Bools) Bools() []bool { |
|||
out := make([]bool, len(b)) |
|||
copy(out, b) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (b Bools) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (b Bools) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewBool(in bool) Read { |
|||
return Read{ParseValue: Bool(in)} |
|||
} |
|||
|
|||
type Bool bool |
|||
|
|||
func (b Bool) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*bool) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect: *bool got: %T", ErrWrongType, val) |
|||
} |
|||
|
|||
*v = bool(b) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (b Bool) ParseString() (string, error) { |
|||
return fmt.Sprintf("%v", b), nil |
|||
} |
|||
|
|||
func (b Bool) ParseInt() (int, error) { |
|||
if b { |
|||
return 1, nil |
|||
} |
|||
|
|||
return 0, nil |
|||
} |
|||
|
|||
func (b Bool) ParseInt64() (int64, error) { |
|||
if b { |
|||
return 1, nil |
|||
} |
|||
|
|||
return 0, nil |
|||
} |
|||
|
|||
func (b Bool) ParseUint() (uint, error) { |
|||
if b { |
|||
return 1, nil |
|||
} |
|||
|
|||
return 0, nil |
|||
} |
|||
|
|||
func (b Bool) ParseUint64() (uint64, error) { |
|||
if b { |
|||
return 1, nil |
|||
} |
|||
|
|||
return 0, nil |
|||
} |
|||
|
|||
func (b Bool) ParseFloat64() (float64, error) { |
|||
if b { |
|||
return 1, nil |
|||
} |
|||
|
|||
return 0, nil |
|||
} |
|||
|
|||
func (b Bool) ParseBool() (bool, error) { |
|||
return bool(b), nil |
|||
} |
|||
|
|||
func (b Bool) ParseDuration() (time.Duration, error) { |
|||
return 0, fmt.Errorf("bool to duration:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (b Bool) ParseTime() (time.Time, error) { |
|||
return time.Time{}, fmt.Errorf("bool to time:%w", ErrWrongType) |
|||
} |
|||
|
|||
return b.Bool() |
|||
func (b Bool) Any() interface{} { |
|||
return bool(b) |
|||
} |
|||
|
@ -1,44 +1,128 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Duration(0) |
|||
_ SliceValue = Durations{} |
|||
) |
|||
|
|||
type Duration struct { |
|||
empty |
|||
Val []time.Duration |
|||
Flag flag.Flag |
|||
func NewDurations(in []time.Duration) Slice { |
|||
return Slice{SliceValue: Durations(in)} |
|||
} |
|||
|
|||
func (d *Duration) Append(in string) error { |
|||
v, err := time.ParseDuration(in) |
|||
if err != nil { |
|||
return err |
|||
type Durations []time.Duration |
|||
|
|||
func (d Durations) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*[]time.Duration) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect: *[]time.Duration got: %T", ErrWrongType, val) |
|||
} |
|||
|
|||
d.Val = append(d.Val, v) |
|||
*v = d |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (d *Duration) Duration() time.Duration { |
|||
if !d.Flag.IsArray() && len(d.Val) == 1 { |
|||
return d.Val[0] |
|||
func (d Durations) Any() interface{} { |
|||
return d.Durations() |
|||
} |
|||
|
|||
return 0 |
|||
func (d Durations) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (d *Duration) Durations() []time.Duration { |
|||
return d.Val |
|||
func (d Durations) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (d *Duration) Any() interface{} { |
|||
if d.Flag.IsArray() { |
|||
return d.Durations() |
|||
func (d Durations) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (d Durations) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (d Durations) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (d Durations) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (d Durations) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (d Durations) Durations() []time.Duration { |
|||
out := make([]time.Duration, len(d)) |
|||
copy(out, d) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (d Durations) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewDuration(in time.Duration) Read { |
|||
return Read{ParseValue: Duration(in)} |
|||
} |
|||
|
|||
type Duration time.Duration |
|||
|
|||
func (d Duration) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseString() (string, error) { |
|||
return time.Duration(d).String(), nil |
|||
} |
|||
|
|||
func (d Duration) ParseInt() (int, error) { |
|||
return int(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseInt64() (int64, error) { |
|||
return int64(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseUint() (uint, error) { |
|||
return uint(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseUint64() (uint64, error) { |
|||
return uint64(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseFloat64() (float64, error) { |
|||
return float64(d), nil |
|||
} |
|||
|
|||
func (d Duration) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("duration:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (d Duration) ParseTime() (time.Time, error) { |
|||
return time.Time{}, fmt.Errorf("duration:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (d Duration) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*time.Duration) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect: *[]time.Duration got: %T", ErrWrongType, val) |
|||
} |
|||
|
|||
*v = time.Duration(d) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
return d.Duration() |
|||
func (d Duration) Any() interface{} { |
|||
return time.Duration(d) |
|||
} |
|||
|
@ -1,100 +0,0 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"time" |
|||
) |
|||
|
|||
// nolint: gochecknoglobals
|
|||
var ( |
|||
emptyValue = &empty{} |
|||
) |
|||
|
|||
func Empty() Value { |
|||
return emptyValue |
|||
} |
|||
|
|||
func IsEmpty(v Value) bool { |
|||
return v == nil || v == emptyValue |
|||
} |
|||
|
|||
type empty struct{} |
|||
|
|||
func (e *empty) Append(string) error { |
|||
return ErrAppendEmpty |
|||
} |
|||
|
|||
func (e *empty) String() string { |
|||
return "" |
|||
} |
|||
|
|||
func (e *empty) Int() int { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Int64() int64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Uint() uint { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Uint64() uint64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Float64() float64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Bool() bool { |
|||
return false |
|||
} |
|||
|
|||
func (e *empty) Duration() time.Duration { |
|||
return 0 |
|||
} |
|||
|
|||
func (e *empty) Time() time.Time { |
|||
return time.Time{} |
|||
} |
|||
|
|||
func (e *empty) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func (e *empty) Any() interface{} { |
|||
return nil |
|||
} |
@ -1,44 +1,128 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"strconv" |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Float64(0) |
|||
_ SliceValue = Float64s{} |
|||
) |
|||
|
|||
type Float64 struct { |
|||
empty |
|||
Val []float64 |
|||
Flag flag.Flag |
|||
func NewFloat64s(in []float64) Slice { |
|||
return Slice{SliceValue: Float64s(in)} |
|||
} |
|||
|
|||
func (f *Float64) Append(in string) error { |
|||
v, err := strconv.ParseFloat(in, 64) |
|||
if err != nil { |
|||
return err |
|||
type Float64s []float64 |
|||
|
|||
func (f Float64s) Any() interface{} { |
|||
return f.Float64s() |
|||
} |
|||
|
|||
f.Val = append(f.Val, v) |
|||
func (f Float64s) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*[]float64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]float64", ErrWrongType) |
|||
} |
|||
|
|||
*v = f |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (f *Float64) Float64() float64 { |
|||
if !f.Flag.IsArray() && len(f.Val) == 1 { |
|||
return f.Val[0] |
|||
func (f Float64s) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
return 0 |
|||
func (f Float64s) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (f *Float64) Float64s() []float64 { |
|||
return f.Val |
|||
func (f Float64s) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (f *Float64) Any() interface{} { |
|||
if f.Flag.IsArray() { |
|||
return f.Float64s() |
|||
func (f Float64s) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (f Float64s) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (f Float64s) Float64s() []float64 { |
|||
out := make([]float64, len(f)) |
|||
copy(out, f) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (f Float64s) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (f Float64s) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (f Float64s) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewFloat64(in float64) Read { |
|||
return Read{ParseValue: Float64(in)} |
|||
} |
|||
|
|||
type Float64 float64 |
|||
|
|||
func (f Float64) Any() interface{} { |
|||
return float64(f) |
|||
} |
|||
|
|||
func (f Float64) ParseString() (string, error) { |
|||
return fmt.Sprint(float64(f)), nil |
|||
} |
|||
|
|||
func (f Float64) ParseInt() (int, error) { |
|||
return int(f), nil |
|||
} |
|||
|
|||
func (f Float64) ParseInt64() (int64, error) { |
|||
return int64(f), nil |
|||
} |
|||
|
|||
func (f Float64) ParseUint() (uint, error) { |
|||
return uint(f), nil |
|||
} |
|||
|
|||
func (f Float64) ParseUint64() (uint64, error) { |
|||
return uint64(f), nil |
|||
} |
|||
|
|||
func (f Float64) ParseFloat64() (float64, error) { |
|||
return float64(f), nil |
|||
} |
|||
|
|||
func (f Float64) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("float64:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (f Float64) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(f), nil |
|||
} |
|||
|
|||
return f.Float64() |
|||
func (f Float64) ParseTime() (time.Time, error) { |
|||
return time.Unix(0, int64(f*Float64(time.Second))), nil |
|||
} |
|||
|
|||
func (f Float64) Unmarshal(in interface{}) error { |
|||
v, ok := in.(*float64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *float64", ErrWrongType) |
|||
} |
|||
|
|||
*v = float64(f) |
|||
|
|||
return nil |
|||
} |
|||
|
@ -0,0 +1,47 @@ |
|||
package value_test |
|||
|
|||
import ( |
|||
"math" |
|||
"testing" |
|||
|
|||
"github.com/stretchr/testify/require" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func TestFloat64_Unmarshal(t *testing.T) { |
|||
t.Parallel() |
|||
|
|||
f := value.Float64(math.Pi) |
|||
|
|||
var out float64 |
|||
|
|||
require.NoError(t, f.Unmarshal(&out)) |
|||
require.Equal(t, math.Pi, out) |
|||
} |
|||
|
|||
func TestFloat64_Any(t *testing.T) { |
|||
t.Parallel() |
|||
|
|||
f := value.Float64(math.Pi) |
|||
|
|||
require.Equal(t, math.Pi, f.Any()) |
|||
} |
|||
|
|||
func TestFloat64s_Unmarshal(t *testing.T) { |
|||
t.Parallel() |
|||
|
|||
f := value.Float64s{math.Pi, math.Sqrt2} |
|||
|
|||
var out []float64 |
|||
|
|||
require.NoError(t, f.Unmarshal(&out)) |
|||
require.Equal(t, []float64{math.Pi, math.Sqrt2}, out) |
|||
} |
|||
|
|||
func TestFloat64s_Any(t *testing.T) { |
|||
t.Parallel() |
|||
|
|||
f := value.Float64s{math.Pi, math.Sqrt2} |
|||
|
|||
require.Equal(t, []float64{math.Pi, math.Sqrt2}, f.Any()) |
|||
} |
@ -1,44 +1,129 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Int(0) |
|||
_ SliceValue = Ints{} |
|||
) |
|||
|
|||
type Int struct { |
|||
empty |
|||
Val []int |
|||
Flag flag.Flag |
|||
func NewInts(in []int) Slice { |
|||
return Slice{SliceValue: Ints(in)} |
|||
} |
|||
|
|||
func (i *Int) Append(in string) error { |
|||
v, err := strconv.Atoi(in) |
|||
if err != nil { |
|||
return err |
|||
type Ints []int |
|||
|
|||
func (i Ints) Unmarshal(in interface{}) error { |
|||
val, ok := in.(*[]int) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]int", ErrWrongType) |
|||
} |
|||
|
|||
i.Val = append(i.Val, v) |
|||
*val = i |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (i *Int) Int() int { |
|||
if !i.Flag.IsArray() && len(i.Val) == 1 { |
|||
return i.Val[0] |
|||
func (i Ints) Any() interface{} { |
|||
return i.Ints() |
|||
} |
|||
|
|||
return 0 |
|||
func (i Ints) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (i *Int) Ints() []int { |
|||
return i.Val |
|||
func (i Ints) Ints() []int { |
|||
out := make([]int, len(i)) |
|||
copy(out, i) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (i *Int) Any() interface{} { |
|||
if i.Flag.IsArray() { |
|||
return i.Ints() |
|||
func (i Ints) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (i Ints) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewInt(in int) Read { |
|||
return Read{ParseValue: Int(in)} |
|||
} |
|||
|
|||
type Int int |
|||
|
|||
func (i Int) Unmarshal(in interface{}) error { |
|||
v, ok := in.(*int) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *int", ErrWrongType) |
|||
} |
|||
|
|||
*v = int(i) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (i Int) ParseString() (string, error) { |
|||
return strconv.Itoa(int(i)), nil |
|||
} |
|||
|
|||
func (i Int) ParseInt() (int, error) { |
|||
return int(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseInt64() (int64, error) { |
|||
return int64(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseUint() (uint, error) { |
|||
return uint(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseUint64() (uint64, error) { |
|||
return uint64(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseFloat64() (float64, error) { |
|||
return float64(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("int:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (i Int) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(i), nil |
|||
} |
|||
|
|||
func (i Int) ParseTime() (time.Time, error) { |
|||
return time.Unix(0, int64(i)), nil |
|||
} |
|||
|
|||
return i.Int() |
|||
func (i Int) Any() interface{} { |
|||
return int(i) |
|||
} |
|||
|
@ -1,44 +1,129 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Int64(0) |
|||
_ SliceValue = Int64s{} |
|||
) |
|||
|
|||
type Int64 struct { |
|||
empty |
|||
Val []int64 |
|||
Flag flag.Flag |
|||
func NewInt64s(in []int64) Slice { |
|||
return Slice{SliceValue: Int64s(in)} |
|||
} |
|||
|
|||
func (i *Int64) Int64() int64 { |
|||
if !i.Flag.IsArray() && len(i.Val) == 1 { |
|||
return i.Val[0] |
|||
type Int64s []int64 |
|||
|
|||
func (i Int64s) Any() interface{} { |
|||
return i.Int64s() |
|||
} |
|||
|
|||
return 0 |
|||
func (i Int64s) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*[]int64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]int64", ErrWrongType) |
|||
} |
|||
|
|||
func (i *Int64) Int64s() []int64 { |
|||
return i.Val |
|||
*v = i |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (i *Int64) Any() interface{} { |
|||
if i.Flag.IsArray() { |
|||
return i.Int64s() |
|||
func (i Int64s) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Int64s() []int64 { |
|||
out := make([]int64, len(i)) |
|||
copy(out, i) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (i Int64s) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (i Int64s) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewInt64(in int64) Read { |
|||
return Read{ParseValue: Int64(in)} |
|||
} |
|||
|
|||
type Int64 int64 |
|||
|
|||
func (i Int64) Any() interface{} { |
|||
return int64(i) |
|||
} |
|||
|
|||
func (i Int64) ParseString() (string, error) { |
|||
return strconv.FormatInt(int64(i), 10), nil |
|||
} |
|||
|
|||
func (i Int64) ParseInt() (int, error) { |
|||
return int(i), nil |
|||
} |
|||
|
|||
func (i Int64) ParseInt64() (int64, error) { |
|||
return int64(i), nil |
|||
} |
|||
|
|||
func (i Int64) ParseUint() (uint, error) { |
|||
return uint(i), nil |
|||
} |
|||
|
|||
func (i Int64) ParseUint64() (uint64, error) { |
|||
return uint64(i), nil |
|||
} |
|||
|
|||
func (i Int64) ParseFloat64() (float64, error) { |
|||
return float64(i), nil |
|||
} |
|||
|
|||
func (i Int64) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("int64:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (i Int64) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(i), nil |
|||
} |
|||
|
|||
return i.Int64() |
|||
func (i Int64) ParseTime() (time.Time, error) { |
|||
return time.Unix(0, int64(i)), nil |
|||
} |
|||
|
|||
func (i *Int64) Append(in string) error { |
|||
v, err := strconv.ParseInt(in, 10, 64) |
|||
if err != nil { |
|||
return err |
|||
func (i Int64) Unmarshal(val interface{}) error { |
|||
v, ok := val.(*int64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *int64", ErrWrongType) |
|||
} |
|||
|
|||
i.Val = append(i.Val, v) |
|||
*v = int64(i) |
|||
|
|||
return nil |
|||
} |
|||
|
@ -1,20 +1,189 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"errors" |
|||
) |
|||
"fmt" |
|||
"time" |
|||
|
|||
var _ Append = (*Read)(nil) |
|||
"gitoa.ru/go-4devs/console/input/errs" |
|||
) |
|||
|
|||
var ( |
|||
ErrAppendRead = errors.New("invalid append data to read value") |
|||
ErrAppendEmpty = errors.New("invalid apped data to empty value") |
|||
_ Value = Read{} |
|||
_ Value = Slice{} |
|||
) |
|||
|
|||
var ErrWrongType = errs.ErrWrongType |
|||
|
|||
type Read struct { |
|||
Value |
|||
ParseValue |
|||
} |
|||
|
|||
func (r Read) String() string { |
|||
sout, _ := r.ParseValue.ParseString() |
|||
|
|||
return sout |
|||
} |
|||
|
|||
func (r Read) Int() int { |
|||
iout, _ := r.ParseValue.ParseInt() |
|||
|
|||
return iout |
|||
} |
|||
|
|||
func (r Read) Int64() int64 { |
|||
iout, _ := r.ParseValue.ParseInt64() |
|||
|
|||
return iout |
|||
} |
|||
|
|||
func (r Read) Uint() uint { |
|||
uout, _ := r.ParseValue.ParseUint() |
|||
|
|||
return uout |
|||
} |
|||
|
|||
func (r Read) Uint64() uint64 { |
|||
uout, _ := r.ParseValue.ParseUint64() |
|||
|
|||
return uout |
|||
} |
|||
|
|||
func (r Read) Float64() float64 { |
|||
fout, _ := r.ParseValue.ParseFloat64() |
|||
|
|||
return fout |
|||
} |
|||
|
|||
func (r Read) Bool() bool { |
|||
bout, _ := r.ParseValue.ParseBool() |
|||
|
|||
return bout |
|||
} |
|||
|
|||
func (r Read) Duration() time.Duration { |
|||
dout, _ := r.ParseValue.ParseDuration() |
|||
|
|||
return dout |
|||
} |
|||
|
|||
func (r Read) Time() time.Time { |
|||
tout, _ := r.ParseValue.ParseTime() |
|||
|
|||
return tout |
|||
} |
|||
|
|||
func (r Read) Strings() []string { |
|||
return []string{r.String()} |
|||
} |
|||
|
|||
func (r Read) Ints() []int { |
|||
return []int{r.Int()} |
|||
} |
|||
|
|||
func (r Read) Int64s() []int64 { |
|||
return []int64{r.Int64()} |
|||
} |
|||
|
|||
func (r Read) Uints() []uint { |
|||
return []uint{r.Uint()} |
|||
} |
|||
|
|||
func (r Read) Uint64s() []uint64 { |
|||
return []uint64{r.Uint64()} |
|||
} |
|||
|
|||
func (r Read) Float64s() []float64 { |
|||
return []float64{r.Float64()} |
|||
} |
|||
|
|||
func (r Read) Bools() []bool { |
|||
return []bool{r.Bool()} |
|||
} |
|||
|
|||
func (r Read) Durations() []time.Duration { |
|||
return []time.Duration{r.Duration()} |
|||
} |
|||
|
|||
func (r Read) Times() []time.Time { |
|||
return []time.Time{r.Time()} |
|||
} |
|||
|
|||
type Slice struct { |
|||
SliceValue |
|||
} |
|||
|
|||
func (s Slice) String() string { |
|||
return "" |
|||
} |
|||
|
|||
func (s Slice) Int() int { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Int64() int64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Uint() uint { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Uint64() uint64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Float64() float64 { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Bool() bool { |
|||
return false |
|||
} |
|||
|
|||
func (s Slice) Duration() time.Duration { |
|||
return 0 |
|||
} |
|||
|
|||
func (s Slice) Time() time.Time { |
|||
return time.Time{} |
|||
} |
|||
|
|||
func (s Slice) wrongType() error { |
|||
return fmt.Errorf("%w: for %T", ErrWrongType, s.SliceValue) |
|||
} |
|||
|
|||
func (s Slice) ParseString() (string, error) { |
|||
return "", s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseInt() (int, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseInt64() (int64, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseUint() (uint, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseUint64() (uint64, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseFloat64() (float64, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseBool() (bool, error) { |
|||
return false, s.wrongType() |
|||
} |
|||
|
|||
func (s Slice) ParseDuration() (time.Duration, error) { |
|||
return 0, s.wrongType() |
|||
} |
|||
|
|||
func (r *Read) Append(string) error { |
|||
return ErrAppendRead |
|||
func (s Slice) ParseTime() (time.Time, error) { |
|||
return time.Time{}, s.wrongType() |
|||
} |
|||
|
@ -1,39 +1,172 @@ |
|||
package value |
|||
|
|||
import "gitoa.ru/go-4devs/console/input/value/flag" |
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
type String struct { |
|||
empty |
|||
Val []string |
|||
Flag flag.Flag |
|||
var ( |
|||
_ ParseValue = (String)("") |
|||
_ SliceValue = (Strings)(nil) |
|||
) |
|||
|
|||
func NewStrings(in []string) Slice { |
|||
return Slice{SliceValue: Strings(in)} |
|||
} |
|||
|
|||
func (s *String) Append(in string) error { |
|||
s.Val = append(s.Val, in) |
|||
type Strings []string |
|||
|
|||
func (s Strings) Unmarshal(in interface{}) error { |
|||
val, ok := in.(*[]string) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]string", ErrWrongType) |
|||
} |
|||
|
|||
*val = s |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (s *String) String() string { |
|||
if s.Flag.IsArray() { |
|||
return "" |
|||
func (s Strings) Any() interface{} { |
|||
return s.Strings() |
|||
} |
|||
|
|||
if len(s.Val) == 1 { |
|||
return s.Val[0] |
|||
func (s Strings) Strings() []string { |
|||
out := make([]string, len(s)) |
|||
copy(out, s) |
|||
|
|||
return out |
|||
} |
|||
|
|||
return "" |
|||
func (s Strings) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (s *String) Strings() []string { |
|||
return s.Val |
|||
func (s Strings) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (s *String) Any() interface{} { |
|||
if s.Flag.IsArray() { |
|||
return s.Strings() |
|||
func (s Strings) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (s Strings) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (s Strings) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (s Strings) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (s Strings) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (s Strings) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewString(in string) Value { |
|||
return Read{ParseValue: String(in)} |
|||
} |
|||
|
|||
type String string |
|||
|
|||
func (s String) ParseString() (string, error) { |
|||
return string(s), nil |
|||
} |
|||
|
|||
func (s String) Unmarshal(in interface{}) error { |
|||
v, ok := in.(*string) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *string", ErrWrongType) |
|||
} |
|||
|
|||
*v = string(s) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (s String) Any() interface{} { |
|||
return string(s) |
|||
} |
|||
|
|||
func (s String) ParseInt() (int, error) { |
|||
v, err := strconv.Atoi(string(s)) |
|||
if err != nil { |
|||
return 0, fmt.Errorf("string int:%w", err) |
|||
} |
|||
|
|||
return v, nil |
|||
} |
|||
|
|||
func (s String) Int64() int64 { |
|||
out, _ := s.ParseInt64() |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (s String) ParseInt64() (int64, error) { |
|||
v, err := strconv.ParseInt(string(s), 10, 64) |
|||
if err != nil { |
|||
return 0, fmt.Errorf("string int64:%w", err) |
|||
} |
|||
|
|||
return v, nil |
|||
} |
|||
|
|||
func (s String) ParseUint() (uint, error) { |
|||
uout, err := s.ParseUint64() |
|||
|
|||
return uint(uout), err |
|||
} |
|||
|
|||
func (s String) ParseUint64() (uint64, error) { |
|||
uout, err := strconv.ParseUint(string(s), 10, 64) |
|||
if err != nil { |
|||
return 0, fmt.Errorf("string uint:%w", err) |
|||
} |
|||
|
|||
return uout, nil |
|||
} |
|||
|
|||
func (s String) ParseFloat64() (float64, error) { |
|||
fout, err := strconv.ParseFloat(string(s), 64) |
|||
if err != nil { |
|||
return 0, fmt.Errorf("string float64:%w", err) |
|||
} |
|||
|
|||
return fout, nil |
|||
} |
|||
|
|||
func (s String) ParseBool() (bool, error) { |
|||
v, err := strconv.ParseBool(string(s)) |
|||
if err != nil { |
|||
return false, fmt.Errorf("string bool:%w", err) |
|||
} |
|||
|
|||
return v, nil |
|||
} |
|||
|
|||
func (s String) ParseDuration() (time.Duration, error) { |
|||
v, err := time.ParseDuration(string(s)) |
|||
if err != nil { |
|||
return 0, fmt.Errorf("string duration:%w", err) |
|||
} |
|||
|
|||
return v, nil |
|||
} |
|||
|
|||
func (s String) ParseTime() (time.Time, error) { |
|||
v, err := time.Parse(time.RFC3339, string(s)) |
|||
if err != nil { |
|||
return time.Time{}, fmt.Errorf("string time:%w", err) |
|||
} |
|||
|
|||
return s.String() |
|||
return v, nil |
|||
} |
|||
|
@ -0,0 +1,28 @@ |
|||
package value_test |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/stretchr/testify/require" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func TestStringUnmarshal(t *testing.T) { |
|||
t.Parallel() |
|||
|
|||
st := value.New("test") |
|||
sta := value.New([]string{"test1", "test2"}) |
|||
|
|||
ac := "" |
|||
require.NoError(t, st.Unmarshal(&ac)) |
|||
require.Equal(t, "test", ac) |
|||
|
|||
aca := []string{} |
|||
require.NoError(t, sta.Unmarshal(&aca)) |
|||
require.Equal(t, []string{"test1", "test2"}, aca) |
|||
|
|||
require.ErrorIs(t, sta.Unmarshal(ac), value.ErrWrongType) |
|||
require.ErrorIs(t, sta.Unmarshal(&ac), value.ErrWrongType) |
|||
require.ErrorIs(t, st.Unmarshal(aca), value.ErrWrongType) |
|||
require.ErrorIs(t, st.Unmarshal(&aca), value.ErrWrongType) |
|||
} |
@ -1,44 +1,130 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Time{time.Now()} |
|||
_ SliceValue = (Times)(nil) |
|||
) |
|||
|
|||
type Time struct { |
|||
empty |
|||
Val []time.Time |
|||
Flag flag.Flag |
|||
func NewTimes(in []time.Time) Slice { |
|||
return Slice{SliceValue: Times(in)} |
|||
} |
|||
|
|||
func (t *Time) Append(in string) error { |
|||
v, err := time.Parse(time.RFC3339, in) |
|||
if err != nil { |
|||
return err |
|||
type Times []time.Time |
|||
|
|||
func (t Times) Any() interface{} { |
|||
return t.Times() |
|||
} |
|||
|
|||
t.Val = append(t.Val, v) |
|||
func (t Times) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*[]time.Time) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]time.Time", ErrWrongType) |
|||
} |
|||
|
|||
*res = t |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (t Times) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
func (t *Time) Time() time.Time { |
|||
if !t.Flag.IsArray() && len(t.Val) == 1 { |
|||
return t.Val[0] |
|||
func (t Times) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
return time.Time{} |
|||
func (t Times) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (t *Time) Times() []time.Time { |
|||
return t.Val |
|||
func (t Times) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (t *Time) Amy() interface{} { |
|||
if t.Flag.IsArray() { |
|||
return t.Times() |
|||
func (t Times) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (t Times) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (t Times) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (t Times) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (t Times) Times() []time.Time { |
|||
out := make([]time.Time, len(t)) |
|||
copy(out, t) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func NewTime(in time.Time) Read { |
|||
return Read{ParseValue: Time{Time: in}} |
|||
} |
|||
|
|||
type Time struct { |
|||
time.Time |
|||
} |
|||
|
|||
func (t Time) ParseString() (string, error) { |
|||
return t.Format(time.RFC3339), nil |
|||
} |
|||
|
|||
func (t Time) ParseInt() (int, error) { |
|||
return int(t.Unix()), nil |
|||
} |
|||
|
|||
func (t Time) ParseInt64() (int64, error) { |
|||
return t.Unix(), nil |
|||
} |
|||
|
|||
func (t Time) ParseUint() (uint, error) { |
|||
return uint(t.Unix()), nil |
|||
} |
|||
|
|||
func (t Time) ParseUint64() (uint64, error) { |
|||
return uint64(t.Unix()), nil |
|||
} |
|||
|
|||
func (t Time) ParseFloat64() (float64, error) { |
|||
return float64(t.UnixNano()), nil |
|||
} |
|||
|
|||
func (t Time) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("time bool:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (t Time) ParseDuration() (time.Duration, error) { |
|||
return 0, fmt.Errorf("time duration:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (t Time) ParseTime() (time.Time, error) { |
|||
return t.Time, nil |
|||
} |
|||
|
|||
func (t Time) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*time.Time) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *time.Time", ErrWrongType) |
|||
} |
|||
|
|||
*res = t.Time |
|||
|
|||
return nil |
|||
} |
|||
|
|||
return t.Time() |
|||
func (t Time) Any() interface{} { |
|||
return t.Time |
|||
} |
|||
|
@ -1,44 +1,129 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Uint(0) |
|||
_ SliceValue = (Uints)(nil) |
|||
) |
|||
|
|||
type Uint struct { |
|||
empty |
|||
Val []uint |
|||
Flag flag.Flag |
|||
func NewUints(in []uint) Slice { |
|||
return Slice{SliceValue: Uints(in)} |
|||
} |
|||
|
|||
func (u *Uint) Append(in string) error { |
|||
v, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return err |
|||
type Uints []uint |
|||
|
|||
func (u Uints) Any() interface{} { |
|||
return u.Uints() |
|||
} |
|||
|
|||
u.Val = append(u.Val, uint(v)) |
|||
func (u Uints) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*[]uint) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]uint", ErrWrongType) |
|||
} |
|||
|
|||
*res = u |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint) Uint() uint { |
|||
if !u.Flag.IsArray() && len(u.Val) == 1 { |
|||
return u.Val[0] |
|||
func (u Uints) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
return 0 |
|||
func (u Uints) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint) Uints() []uint { |
|||
return u.Val |
|||
func (u Uints) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint) Any() interface{} { |
|||
if u.Flag.IsArray() { |
|||
return u.Uints() |
|||
func (u Uints) Uints() []uint { |
|||
out := make([]uint, len(u)) |
|||
copy(out, u) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (u Uints) Uint64s() []uint64 { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uints) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uints) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uints) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uints) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewUint(in uint) Read { |
|||
return Read{ParseValue: Uint(in)} |
|||
} |
|||
|
|||
type Uint uint |
|||
|
|||
func (u Uint) ParseString() (string, error) { |
|||
return strconv.FormatUint(uint64(u), 10), nil |
|||
} |
|||
|
|||
func (u Uint) ParseInt() (int, error) { |
|||
return int(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseInt64() (int64, error) { |
|||
return int64(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseUint() (uint, error) { |
|||
return uint(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseUint64() (uint64, error) { |
|||
return uint64(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseFloat64() (float64, error) { |
|||
return float64(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("uint:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (u Uint) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(u), nil |
|||
} |
|||
|
|||
func (u Uint) ParseTime() (time.Time, error) { |
|||
return time.Unix(0, int64(u)), nil |
|||
} |
|||
|
|||
func (u Uint) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*uint) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *uint", ErrWrongType) |
|||
} |
|||
|
|||
*res = uint(u) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
return u.Uint() |
|||
func (u Uint) Any() interface{} { |
|||
return uint(u) |
|||
} |
|||
|
@ -1,44 +1,129 @@ |
|||
package value |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
"gitoa.ru/go-4devs/console/input/value/flag" |
|||
var ( |
|||
_ ParseValue = Uint64(0) |
|||
_ SliceValue = (Uint64s)(nil) |
|||
) |
|||
|
|||
type Uint64 struct { |
|||
empty |
|||
Val []uint64 |
|||
Flag flag.Flag |
|||
func NewUint64s(in []uint64) Slice { |
|||
return Slice{SliceValue: Uint64s(in)} |
|||
} |
|||
|
|||
func (u *Uint64) Append(in string) error { |
|||
v, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return err |
|||
type Uint64s []uint64 |
|||
|
|||
func (u Uint64s) Any() interface{} { |
|||
return u.Uint64s() |
|||
} |
|||
|
|||
u.Val = append(u.Val, v) |
|||
func (u Uint64s) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*[]uint64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *[]uint64", ErrWrongType) |
|||
} |
|||
|
|||
*res = u |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint64) Uint64() uint64 { |
|||
if !u.Flag.IsArray() && len(u.Val) == 1 { |
|||
return u.Val[0] |
|||
func (u Uint64s) Strings() []string { |
|||
return nil |
|||
} |
|||
|
|||
return 0 |
|||
func (u Uint64s) Ints() []int { |
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint64) Uint64s() []uint64 { |
|||
return u.Val |
|||
func (u Uint64s) Int64s() []int64 { |
|||
return nil |
|||
} |
|||
|
|||
func (u *Uint64) Any() interface{} { |
|||
if u.Flag.IsArray() { |
|||
return u.Uint64s() |
|||
func (u Uint64s) Uints() []uint { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uint64s) Uint64s() []uint64 { |
|||
out := make([]uint64, len(u)) |
|||
copy(out, u) |
|||
|
|||
return out |
|||
} |
|||
|
|||
func (u Uint64s) Float64s() []float64 { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uint64s) Bools() []bool { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uint64s) Durations() []time.Duration { |
|||
return nil |
|||
} |
|||
|
|||
func (u Uint64s) Times() []time.Time { |
|||
return nil |
|||
} |
|||
|
|||
func NewUint64(in uint64) Read { |
|||
return Read{ParseValue: Uint64(in)} |
|||
} |
|||
|
|||
type Uint64 uint64 |
|||
|
|||
func (u Uint64) ParseString() (string, error) { |
|||
return strconv.FormatUint(uint64(u), 10), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseInt() (int, error) { |
|||
return int(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseInt64() (int64, error) { |
|||
return int64(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseUint() (uint, error) { |
|||
return uint(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseUint64() (uint64, error) { |
|||
return uint64(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseFloat64() (float64, error) { |
|||
return float64(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseBool() (bool, error) { |
|||
return false, fmt.Errorf("uint64 bool:%w", ErrWrongType) |
|||
} |
|||
|
|||
func (u Uint64) ParseDuration() (time.Duration, error) { |
|||
return time.Duration(u), nil |
|||
} |
|||
|
|||
func (u Uint64) ParseTime() (time.Time, error) { |
|||
return time.Unix(0, int64(0)), nil |
|||
} |
|||
|
|||
func (u Uint64) Unmarshal(val interface{}) error { |
|||
res, ok := val.(*uint64) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *uint64", ErrWrongType) |
|||
} |
|||
|
|||
*res = uint64(u) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
return u.Uint64() |
|||
func (u Uint64) Any() interface{} { |
|||
return uint64(u) |
|||
} |
|||
|
@ -0,0 +1,10 @@ |
|||
package variable |
|||
|
|||
//go:generate stringer -type=ArgType -linecomment
|
|||
|
|||
type ArgType int |
|||
|
|||
const ( |
|||
TypeOption ArgType = iota + 1 // option
|
|||
TypeArgument // argument
|
|||
) |
@ -0,0 +1,25 @@ |
|||
// Code generated by "stringer -type=ArgType -linecomment"; DO NOT EDIT.
|
|||
|
|||
package variable |
|||
|
|||
import "strconv" |
|||
|
|||
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[TypeOption-1] |
|||
_ = x[TypeArgument-2] |
|||
} |
|||
|
|||
const _ArgType_name = "optionargument" |
|||
|
|||
var _ArgType_index = [...]uint8{0, 6, 14} |
|||
|
|||
func (i ArgType) String() string { |
|||
i -= 1 |
|||
if i < 0 || i >= ArgType(len(_ArgType_index)-1) { |
|||
return "ArgType(" + strconv.FormatInt(int64(i+1), 10) + ")" |
|||
} |
|||
return _ArgType_name[_ArgType_index[i]:_ArgType_index[i+1]] |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Bool(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, WithParse(CreateBool, AppendBool), Value(flag.Bool))...) |
|||
} |
|||
|
|||
func CreateBool(in string) (value.Value, error) { |
|||
out, err := strconv.ParseBool(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create bool:%w", err) |
|||
} |
|||
|
|||
return value.NewBool(out), nil |
|||
} |
|||
|
|||
func AppendBool(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.ParseBool(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create bool:%w", err) |
|||
} |
|||
|
|||
return value.NewBools(append(old.Bools(), out)), nil |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Duration(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, WithParse(CreateDuration, AppendDuration), Value(flag.Duration))...) |
|||
} |
|||
|
|||
func CreateDuration(in string) (value.Value, error) { |
|||
out, err := time.ParseDuration(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create duration:%w", err) |
|||
} |
|||
|
|||
return value.NewDuration(out), nil |
|||
} |
|||
|
|||
func AppendDuration(old value.Value, in string) (value.Value, error) { |
|||
out, err := time.ParseDuration(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append duration:%w", err) |
|||
} |
|||
|
|||
return value.NewDurations(append(old.Durations(), out)), nil |
|||
} |
@ -0,0 +1,32 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"errors" |
|||
"fmt" |
|||
) |
|||
|
|||
type Error struct { |
|||
Name string |
|||
Err error |
|||
Type ArgType |
|||
} |
|||
|
|||
func (o Error) Error() string { |
|||
return fmt.Sprintf("%s: '%s' %s", o.Type, o.Name, o.Err) |
|||
} |
|||
|
|||
func (o Error) Is(err error) bool { |
|||
return errors.Is(err, o.Err) |
|||
} |
|||
|
|||
func (o Error) Unwrap() error { |
|||
return o.Err |
|||
} |
|||
|
|||
func Err(name string, t ArgType, err error) Error { |
|||
return Error{ |
|||
Name: name, |
|||
Type: t, |
|||
Err: err, |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Float64(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, WithParse(CreateFloat64, AppendFloat64), Value(flag.Float64))...) |
|||
} |
|||
|
|||
func CreateFloat64(in string) (value.Value, error) { |
|||
out, err := strconv.ParseFloat(in, 10) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create float64:%w", err) |
|||
} |
|||
|
|||
return value.NewFloat64(out), nil |
|||
} |
|||
|
|||
func AppendFloat64(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.ParseFloat(in, 10) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append float64:%w", err) |
|||
} |
|||
|
|||
return value.NewFloat64s(append(old.Float64s(), out)), nil |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Int(name, description string, opts ...Option) Variable { |
|||
return New(name, description, append(opts, WithParse(CreateInt, AppendInt), Value(flag.Int))...) |
|||
} |
|||
|
|||
func AppendInt(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.Atoi(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append int:%w", err) |
|||
} |
|||
|
|||
return value.NewInts(append(old.Ints(), out)), nil |
|||
} |
|||
|
|||
func CreateInt(in string) (value.Value, error) { |
|||
out, err := strconv.Atoi(in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create int:%w", err) |
|||
} |
|||
|
|||
return value.NewInt(out), nil |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Int64(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, WithParse(CreateInt64, AppendInt64), Value(flag.Int64))...) |
|||
} |
|||
|
|||
func CreateInt64(in string) (value.Value, error) { |
|||
out, err := strconv.ParseInt(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create int64:%w", err) |
|||
} |
|||
|
|||
return value.NewInt64(out), nil |
|||
} |
|||
|
|||
func AppendInt64(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.ParseInt(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append int64:%w", err) |
|||
} |
|||
|
|||
return value.NewInt64s(append(old.Int64s(), out)), nil |
|||
} |
@ -0,0 +1,17 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func String(name, description string, opts ...Option) Variable { |
|||
return New(name, description, opts...) |
|||
} |
|||
|
|||
func CreateString(in string) (value.Value, error) { |
|||
return value.NewString(in), nil |
|||
} |
|||
|
|||
func AppendString(old value.Value, in string) (value.Value, error) { |
|||
return value.NewStrings(append(old.Strings(), in)), nil |
|||
} |
@ -0,0 +1,77 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/errs" |
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
const ( |
|||
ParamFormat = "format" |
|||
) |
|||
|
|||
func Time(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, |
|||
WithParamParse(CreateTime, AppendTime), |
|||
WithParam(ParamFormat, RFC3339), |
|||
Value(flag.Time), |
|||
)...) |
|||
} |
|||
|
|||
func RFC3339(in interface{}) error { |
|||
v, ok := in.(*string) |
|||
if !ok { |
|||
return fmt.Errorf("%w: expect *string got %T", errs.ErrWrongType, in) |
|||
} |
|||
|
|||
*v = time.RFC3339 |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func CreateTime(param Param) Create { |
|||
var ( |
|||
formatErr error |
|||
format string |
|||
) |
|||
|
|||
formatErr = param.Value(ParamFormat, &format) |
|||
|
|||
return func(in string) (value.Value, error) { |
|||
if formatErr != nil { |
|||
return nil, fmt.Errorf("create format:%w", formatErr) |
|||
} |
|||
|
|||
out, err := time.Parse(format, in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create time:%w", err) |
|||
} |
|||
|
|||
return value.NewTime(out), nil |
|||
} |
|||
} |
|||
|
|||
func AppendTime(param Param) Append { |
|||
var ( |
|||
formatErr error |
|||
format string |
|||
) |
|||
|
|||
formatErr = param.Value(ParamFormat, &format) |
|||
|
|||
return func(old value.Value, in string) (value.Value, error) { |
|||
if formatErr != nil { |
|||
return nil, fmt.Errorf("append format:%w", formatErr) |
|||
} |
|||
|
|||
out, err := time.Parse(format, in) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append time:%w", err) |
|||
} |
|||
|
|||
return value.NewTimes(append(old.Times(), out)), nil |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Uint(name, description string, opts ...Option) Variable { |
|||
return String(name, description, append(opts, WithParse(CreateUint, AppendUint), Value(flag.Uint))...) |
|||
} |
|||
|
|||
func CreateUint(in string) (value.Value, error) { |
|||
out, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create uint:%w", err) |
|||
} |
|||
|
|||
return value.NewUint(uint(out)), nil |
|||
} |
|||
|
|||
func AppendUint(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append uint:%w", err) |
|||
} |
|||
|
|||
return value.NewUints(append(old.Uints(), uint(out))), nil |
|||
} |
@ -0,0 +1,31 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
"strconv" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
func Uint64(name, descriontion string, opts ...Option) Variable { |
|||
return String(name, descriontion, append(opts, WithParse(CreateUint64, AppendUint64), Value(flag.Uint64))...) |
|||
} |
|||
|
|||
func CreateUint64(in string) (value.Value, error) { |
|||
out, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("create uint64:%w", err) |
|||
} |
|||
|
|||
return value.NewUint64(out), nil |
|||
} |
|||
|
|||
func AppendUint64(old value.Value, in string) (value.Value, error) { |
|||
out, err := strconv.ParseUint(in, 10, 64) |
|||
if err != nil { |
|||
return nil, fmt.Errorf("append uint64:%w", err) |
|||
} |
|||
|
|||
return value.NewUint64s(append(old.Uint64s(), out)), nil |
|||
} |
@ -0,0 +1,158 @@ |
|||
package variable |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"gitoa.ru/go-4devs/console/input/errs" |
|||
"gitoa.ru/go-4devs/console/input/flag" |
|||
"gitoa.ru/go-4devs/console/input/value" |
|||
) |
|||
|
|||
type Option func(*Variable) |
|||
|
|||
func WithType(t ArgType) Option { |
|||
return func(v *Variable) { |
|||
v.Type = t |
|||
} |
|||
} |
|||
|
|||
func ArgOption(v *Variable) { |
|||
v.Type = TypeOption |
|||
} |
|||
|
|||
func ArgArgument(v *Variable) { |
|||
v.Type = TypeArgument |
|||
} |
|||
|
|||
func Value(in flag.Flag) Option { |
|||
return func(v *Variable) { |
|||
v.Flag |= in |
|||
} |
|||
} |
|||
|
|||
func Default(in value.Value) Option { |
|||
return func(v *Variable) { |
|||
v.Default = in |
|||
} |
|||
} |
|||
|
|||
func Required(v *Variable) { |
|||
v.Flag |= flag.Required |
|||
} |
|||
|
|||
func WithParse(create Create, update Append) Option { |
|||
return func(v *Variable) { |
|||
v.append = func(Param) Append { return update } |
|||
v.create = func(Param) Create { return create } |
|||
} |
|||
} |
|||
|
|||
func WithParamParse(create func(Param) Create, update func(Param) Append) Option { |
|||
return func(v *Variable) { |
|||
v.append = update |
|||
v.create = create |
|||
} |
|||
} |
|||
|
|||
func Valid(f ...func(value.Value) error) Option { |
|||
return func(v *Variable) { |
|||
v.Valid = f |
|||
} |
|||
} |
|||
|
|||
func Array(o *Variable) { |
|||
o.Flag |= flag.Array |
|||
} |
|||
|
|||
func WithParam(name string, fn func(interface{}) error) Option { |
|||
return func(v *Variable) { |
|||
v.params[name] = fn |
|||
} |
|||
} |
|||
|
|||
type ( |
|||
Create func(s string) (value.Value, error) |
|||
Append func(old value.Value, s string) (value.Value, error) |
|||
) |
|||
|
|||
func New(name, description string, opts ...Option) Variable { |
|||
res := Variable{ |
|||
Name: name, |
|||
Description: description, |
|||
Type: TypeOption, |
|||
create: func(Param) Create { return CreateString }, |
|||
append: func(Param) Append { return AppendString }, |
|||
params: make(Params), |
|||
} |
|||
|
|||
for _, opt := range opts { |
|||
opt(&res) |
|||
} |
|||
|
|||
return res |
|||
} |
|||
|
|||
type Variable struct { |
|||
Name string |
|||
Description string |
|||
Alias string |
|||
Flag flag.Flag |
|||
Type ArgType |
|||
Default value.Value |
|||
Valid []func(value.Value) error |
|||
params Params |
|||
create func(Param) Create |
|||
append func(Param) Append |
|||
} |
|||
|
|||
func (v Variable) Validate(in value.Value) error { |
|||
for _, valid := range v.Valid { |
|||
if err := valid(in); err != nil { |
|||
return Err(v.Name, v.Type, err) |
|||
} |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (v Variable) IsArray() bool { |
|||
return v.Flag.IsArray() |
|||
} |
|||
|
|||
func (v Variable) IsRequired() bool { |
|||
return v.Flag.IsRequired() |
|||
} |
|||
|
|||
func (v Variable) HasDefault() bool { |
|||
return v.Default != nil |
|||
} |
|||
|
|||
func (v Variable) IsBool() bool { |
|||
return v.Flag.IsBool() |
|||
} |
|||
|
|||
func (v Variable) HasShort() bool { |
|||
return v.Type == TypeOption && len(v.Alias) == 1 |
|||
} |
|||
|
|||
func (v Variable) Create(s string) (value.Value, error) { |
|||
return v.create(v.params)(s) |
|||
} |
|||
|
|||
func (v Variable) Append(old value.Value, s string) (value.Value, error) { |
|||
return v.append(v.params)(old, s) |
|||
} |
|||
|
|||
type Param interface { |
|||
Value(name string, v interface{}) error |
|||
} |
|||
|
|||
type Params map[string]func(interface{}) error |
|||
|
|||
func (p Params) Value(name string, v interface{}) error { |
|||
if p, ok := p[name]; ok { |
|||
return p(v) |
|||
} |
|||
|
|||
return fmt.Errorf("%w: param %v", errs.ErrNotFound, name) |
|||
} |
Loading…
Reference in new issue