package input import ( "context" "sync" "gitoa.ru/go-4devs/console/input/errs" "gitoa.ru/go-4devs/console/input/value" ) type Array struct { defaults array value array } func (a *Array) GetOption(name string) (value.Append, bool) { return a.value.GetOption(name) } func (a *Array) SetOption(name string, v interface{}) { a.value.SetOption(name, v) } func (a *Array) LenArguments() int { return a.value.LenArguments() } func (a *Array) GetArgument(name string) (value.Append, bool) { return a.value.GetArgument(name) } func (a *Array) SetArgument(name string, v interface{}) { a.value.SetArgument(name, v) } func (a *Array) Option(_ context.Context, name string) value.Value { if v, ok := a.value.GetOption(name); ok { return v } if v, ok := a.defaults.GetOption(name); ok { return v } return value.Empty } func (a *Array) Argument(_ context.Context, name string) value.Value { if v, ok := a.value.GetArgument(name); ok { return v } if v, ok := a.defaults.GetArgument(name); ok { return v } return value.Empty } func (a *Array) Bind(ctx context.Context, d *Definition) error { if err := a.bindArguments(d); err != nil { return err } return a.bindOption(d) } func (a *Array) bindOption(def *Definition) error { for _, name := range def.Options() { opt, err := def.Option(name) if err != nil { return err } v, ok := a.value.GetOption(name) if !ok { switch { case opt.HasDefault(): a.defaults.SetOption(name, opt.Default) continue case opt.IsRequired(): return errs.Option(name, errs.ErrRequired) default: continue } } a.SetOption(name, v) if err := opt.Validate(v); err != nil { return errs.Option(name, err) } } return nil } func (a *Array) bindArguments(def *Definition) error { for pos, name := range def.Arguments() { arg, err := def.Argument(pos) if err != nil { return err } v, ok := a.value.GetArgument(name) if !ok { switch { case arg.HasDefault(): a.defaults.SetArgument(name, arg.Default) continue case arg.IsRequired(): return errs.Argument(name, errs.ErrRequired) default: continue } } if err := arg.Validate(v); err != nil { return errs.Argument(name, err) } a.SetArgument(name, v) } return nil } type array struct { opts map[string]value.Append args map[string]value.Append mu sync.Mutex } func (a *array) GetOption(name string) (value.Append, bool) { v, ok := a.opts[name] return v, ok } func (a *array) SetOption(name string, v interface{}) { if a.opts == nil { a.opts = make(map[string]value.Append) } a.mu.Lock() a.opts[name] = value.New(v) a.mu.Unlock() } func (a *array) LenArguments() int { return len(a.args) } func (a *array) GetArgument(name string) (value.Append, bool) { v, ok := a.args[name] return v, ok } func (a *array) SetArgument(name string, v interface{}) { if a.args == nil { a.args = make(map[string]value.Append) } a.mu.Lock() a.args[name] = value.New(v) a.mu.Unlock() }