| package mapstructure |
| |
| import ( |
| "reflect" |
| "strconv" |
| "strings" |
| ) |
| |
| // ComposeDecodeHookFunc creates a single DecodeHookFunc that |
| // automatically composes multiple DecodeHookFuncs. |
| // |
| // The composed funcs are called in order, with the result of the |
| // previous transformation. |
| func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { |
| return func( |
| f reflect.Kind, |
| t reflect.Kind, |
| data interface{}) (interface{}, error) { |
| var err error |
| for _, f1 := range fs { |
| data, err = f1(f, t, data) |
| if err != nil { |
| return nil, err |
| } |
| |
| // Modify the from kind to be correct with the new data |
| f = getKind(reflect.ValueOf(data)) |
| } |
| |
| return data, nil |
| } |
| } |
| |
| // StringToSliceHookFunc returns a DecodeHookFunc that converts |
| // string to []string by splitting on the given sep. |
| func StringToSliceHookFunc(sep string) DecodeHookFunc { |
| return func( |
| f reflect.Kind, |
| t reflect.Kind, |
| data interface{}) (interface{}, error) { |
| if f != reflect.String || t != reflect.Slice { |
| return data, nil |
| } |
| |
| raw := data.(string) |
| if raw == "" { |
| return []string{}, nil |
| } |
| |
| return strings.Split(raw, sep), nil |
| } |
| } |
| |
| func WeaklyTypedHook( |
| f reflect.Kind, |
| t reflect.Kind, |
| data interface{}) (interface{}, error) { |
| dataVal := reflect.ValueOf(data) |
| switch t { |
| case reflect.String: |
| switch f { |
| case reflect.Bool: |
| if dataVal.Bool() { |
| return "1", nil |
| } else { |
| return "0", nil |
| } |
| case reflect.Float32: |
| return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil |
| case reflect.Int: |
| return strconv.FormatInt(dataVal.Int(), 10), nil |
| case reflect.Slice: |
| dataType := dataVal.Type() |
| elemKind := dataType.Elem().Kind() |
| if elemKind == reflect.Uint8 { |
| return string(dataVal.Interface().([]uint8)), nil |
| } |
| case reflect.Uint: |
| return strconv.FormatUint(dataVal.Uint(), 10), nil |
| } |
| } |
| |
| return data, nil |
| } |