add map support
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
05720a433e
commit
d6a35346cc
12
flag_test.go
12
flag_test.go
@ -15,12 +15,14 @@ func TestLoad(t *testing.T) {
|
||||
os.Args = append(os.Args, "-wait", "5s")
|
||||
os.Args = append(os.Args, "-addr", "33,44")
|
||||
os.Args = append(os.Args, "-time", time.RFC822)
|
||||
os.Args = append(os.Args, "-metadata", "key=20")
|
||||
type Config struct {
|
||||
Broker string `flag:"name=broker,desc='description with, comma',default='127.0.0.1:9092'"`
|
||||
Verbose bool `flag:"name=verbose,desc='verbose output',default='false'"`
|
||||
Addr []string `flag:"name=addr,desc='addrs',default='127.0.0.1:9092'"`
|
||||
Wait time.Duration `flag:"name=wait,desc='wait time',default='2s'"`
|
||||
Time time.Time `flag:"name=time,desc='some time',default='02 Jan 06 15:04 MST'"`
|
||||
Broker string `flag:"name=broker,desc='description with, comma',default='127.0.0.1:9092'"`
|
||||
Verbose bool `flag:"name=verbose,desc='verbose output',default='false'"`
|
||||
Addr []string `flag:"name=addr,desc='addrs',default='127.0.0.1:9092'"`
|
||||
Wait time.Duration `flag:"name=wait,desc='wait time',default='2s'"`
|
||||
Time time.Time `flag:"name=time,desc='some time',default='02 Jan 06 15:04 MST'"`
|
||||
Metadata map[string]int `flag:"name=metadata,desc='some meta',default=''"`
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
78
util.go
78
util.go
@ -8,6 +8,41 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func convertType(v reflect.Value, t reflect.Kind) (reflect.Value, error) {
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
switch t {
|
||||
case reflect.String:
|
||||
return v, nil
|
||||
case reflect.Int, reflect.Int64:
|
||||
i, err := strconv.ParseInt(v.String(), 10, 64)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
return reflect.ValueOf(i), nil
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
i, err := strconv.ParseUint(v.String(), 10, 64)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
return reflect.ValueOf(i), nil
|
||||
case reflect.Float64:
|
||||
i, err := strconv.ParseFloat(v.String(), 64)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
return reflect.ValueOf(i), nil
|
||||
case reflect.Bool:
|
||||
i, err := strconv.ParseBool(v.String())
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
return reflect.ValueOf(i), nil
|
||||
}
|
||||
}
|
||||
return v, ErrInvalidValue
|
||||
}
|
||||
|
||||
func (c *flagConfig) flagSlice(v reflect.Value, fn, fv, fd string) error {
|
||||
delim := DefaultSliceDelim
|
||||
if c.opts.Context != nil {
|
||||
@ -64,6 +99,49 @@ func (c *flagConfig) flagSlice(v reflect.Value, fn, fv, fd string) error {
|
||||
}
|
||||
|
||||
func (c *flagConfig) flagMap(v reflect.Value, fn, fv, fd string) error {
|
||||
delim := DefaultMapDelim
|
||||
if c.opts.Context != nil {
|
||||
if d, ok := c.opts.Context.Value(mapDelimKey{}).(string); ok {
|
||||
delim = d
|
||||
}
|
||||
}
|
||||
flag.Func(fn, fd, func(s string) error {
|
||||
ps := strings.Split(s, delim)
|
||||
if len(ps) == 0 {
|
||||
return nil
|
||||
}
|
||||
v.Set(reflect.MakeMapWithSize(v.Type(), len(ps)))
|
||||
kt := v.Type().Key().Kind()
|
||||
vt := v.Type().Elem().Kind()
|
||||
|
||||
for i := 0; i < len(ps); i++ {
|
||||
fs := strings.Split(ps[i], "=")
|
||||
switch len(fs) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
if len(fs[0]) == 0 {
|
||||
return nil
|
||||
}
|
||||
return ErrInvalidValue
|
||||
case 2:
|
||||
break
|
||||
default:
|
||||
return ErrInvalidValue
|
||||
}
|
||||
key, err := convertType(reflect.ValueOf(fs[0]), kt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val, err := convertType(reflect.ValueOf(fs[1]), vt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.SetMapIndex(key.Convert(v.Type().Key()), val.Convert(v.Type().Elem()))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user