package value import ( "encoding/json" "fmt" "reflect" "strconv" "strings" ) func ValueOf(val interface{}) Value { return Value{ val: val, } } type Value struct { val interface{} } func (s *Value) IsValid() bool { return s.val != nil } func (s *Value) Setup(val interface{}) (res bool) { rr := reflect.ValueOf(val) if rr.Kind() != reflect.Ptr { panic(fmt.Errorf("Expected ptr, given %v", rr.Type())) } rKind, rType := rr.Elem().Kind(), rr.Elem().Type() if rKind == reflect.Interface { rKind, rType = rr.Elem().Elem().Kind(), rr.Elem().Elem().Type() } if rKind == reflect.String { rls := strings.TrimSpace(fmt.Sprint(s.val)) if len(rls) > 0 { rr.Elem().Set(reflect.ValueOf(rls)) res = true } } else { rl := reflect.ValueOf(s.val) if rl.Kind() == reflect.String { switch rKind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: { if tmp, err := strconv.ParseInt(rl.String(), 10, 64); err == nil { rr.Elem().Set(reflect.ValueOf(tmp).Convert(rType)) res = true } } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: { if tmp, err := strconv.ParseUint(rl.String(), 10, 64); err == nil { rr.Elem().Set(reflect.ValueOf(tmp).Convert(rType)) res = true } } case reflect.Float32, reflect.Float64: { if tmp, err := strconv.ParseFloat(rl.String(), 64); err == nil { rr.Elem().Set(reflect.ValueOf(tmp).Convert(rType)) res = true } } case reflect.Slice: { slType := rType.Elem() if rr.Kind() == reflect.Slice { slRes := reflect.MakeSlice(rType, rr.Len(), rr.Cap()) for i := 0; i < rl.Len(); i++ { if val := rl.Index(i); val.CanConvert(slType) { slRes.Index(i).Set(val.Convert(slType)) } else { return false } } rr.Elem().Set(slRes) res = true } else if rl.Kind() == reflect.String { slType := rType.Elem() sls := strings.Split(rl.String(), ",") slRes := reflect.MakeSlice(rType, len(sls), cap(sls)) for i, sVal := range sls { sItem := reflect.ValueOf(strings.TrimSpace(sVal)) switch { case isKindNumber(slType.Kind()): { numVal, err := strconv.ParseFloat(sItem.String(), 64) if err != nil { return false } sItem = reflect.ValueOf(numVal) slRes.Index(i).Set(sItem.Convert(slType)) } default: { if !sItem.CanConvert(slType) { return false } slRes.Index(i).Set(sItem.Convert(slType)) } } } rr.Elem().Set(slRes) res = true } /* log.Println("Slice") slType := rType.Elem() if rr.Kind() == reflect.Slice { slRes := reflect.MakeSlice(slType, rr.Len(), rr.Cap()) for i := 0; i < rl.Len(); i++ { if val := rl.Index(i); val.CanConvert(slType) { slRes.Index(i).Set(val.Convert(slType)) } else { return false } } rr.Elem().Set(slRes) res = true } else if rl.Kind() == reflect.String { log.Println("sl <===> str") sls := strings.Split(rl.String(), ",") log.Println(slType, rr.Type()) slRes := reflect.MakeSlice(slType, len(sls), cap(sls)) switch { case isKindNumber(slType.Kind()): log.Println("AAAAAAAAAAAAAAAAA") for i, sVal := range sls { numVal, err := strconv.ParseFloat(sVal, 64) if err != nil { return false } rl := reflect.ValueOf(numVal) if val := rl.Index(i); val.CanConvert(slType) { slRes.Index(i).Set(val.Convert(slType)) } else { return false } } rr.Elem().Set(slRes) res = true } } */ } default: // json i := reflect.New(rr.Elem().Type()).Interface() if err := json.Unmarshal([]byte(rl.String()), i); err == nil { rr.Elem().Set(reflect.ValueOf(i).Elem()) } } } else { var rVal reflect.Value defer func() { if r := recover(); r == nil { rr.Elem().Set(rVal) res = true } }() rVal = rl.Convert(rType) } } return } func (s *Value) String() string { return fmt.Sprint(s.val) } func (s *Value) Int() int { var i int s.Setup(&i) return i } func (s *Value) Int8() int8 { var i int8 s.Setup(&i) return i } func (s *Value) Int16() int16 { var i int16 s.Setup(&i) return i } func (s *Value) Int32() int32 { return int32(s.Int()) } func (s *Value) Float32() float32 { var i float32 s.Setup(&i) return i } func (s *Value) Float64() float64 { var i float64 s.Setup(&i) return i }