package args import ( "fmt" "strconv" "strings" "time" ) type Arg struct { Env string Flag string Help string Default interface{} Value interface{} ArgType Type } func NewArg(argType Type, key, help string, def interface{}) *Arg { return &Arg{ Env: strings.ToUpper(key), Flag: strings.ToLower(key), Help: help, Default: def, Value: def, ArgType: argType, } } func (a *Arg) GetInt() int { if a.ArgType != INT { return -1 } if _, ok := a.Value.(int); !ok { return -1 } return a.Value.(int) } func (a *Arg) GetString() string { if a.ArgType != STRING { return "" } if _, ok := a.Value.(string); !ok { return "" } return a.Value.(string) } func (a *Arg) GetBool() bool { if a.ArgType != BOOL { return false } if _, ok := a.Value.(bool); !ok { return false } return a.Value.(bool) } func (a *Arg) GetDuration() time.Duration { if a.ArgType != DURATION { return time.Duration(-1) } if _, ok := a.Value.(time.Duration); !ok { return time.Duration(-1) } return a.Value.(time.Duration) } func (a *Arg) Set(value interface{}) error { err := fmt.Errorf("incompatible set of type %T for arg $%v/-%v type %v", value, a.Env, a.Flag, a.ArgType) switch a.ArgType { case INT: i, ok := value.(int) if ok { a.Value = i err = nil } else if s, ok := value.(string); !ok { } else if i, err = strconv.Atoi(s); err == nil { a.Value = i err = nil } case STRING: i, ok := value.(string) if ok { a.Value = i err = nil } case BOOL: i, ok := value.(bool) if ok { a.Value = i err = nil } else if s, ok := value.(string); !ok { } else if i, err = strconv.ParseBool(s); err == nil { a.Value = i err = nil } case DURATION: i, ok := value.(time.Duration) if ok { a.Value = i err = nil } else if s, ok := value.(string); !ok { } else if i, err = time.ParseDuration(s); err == nil { a.Value = i err = nil } } return err }