args/arg.go

161 lines
3.0 KiB
Go

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
}
case TIME:
if i, ok := value.(time.Duration); ok {
a.Value = time.Now().Add(i)
err = nil
} else if j, ok := value.(time.Time); ok {
a.Value = j
err = nil
} else if s, ok := value.(string); !ok {
} else if i, err = time.ParseDuration(s); err == nil {
a.Value = time.Now().Add(i)
err = nil
} else {
layouts := []string{
"01-02-2006",
"01/02/2006",
"01-02-06",
"01/02/06",
"2006-01-02",
"2006/01/02",
"06-01-02",
"06/01/02",
"2006-01-02 15:04:05.999999999 -0700 MST",
}
for k := range layouts {
if j, err = time.Parse(layouts[k], s); err == nil {
a.Value = j
err = nil
break
}
}
}
case FLOAT:
if i, ok := value.(float32); ok {
a.Value = i
err = nil
} else if j, ok := value.(float64); ok {
a.Value = float32(j)
err = nil
} else if k, ok := value.(int); ok {
a.Value = float32(k)
err = nil
} else if s, ok := value.(string); !ok {
} else if j, err = strconv.ParseFloat(s, 32); err == nil {
a.Value = float32(j)
err = nil
} else if k, err = strconv.Atoi(s); err == nil {
a.Value = float32(k)
err = nil
}
}
return err
}