github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/typeTransform/Transform.go (about) 1 package typeTransform 2 3 import ( 4 "fmt" 5 "math" 6 "reflect" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/bronze1man/kmg/kmgReflect" 12 "github.com/bronze1man/kmg/kmgStrconv" 13 "github.com/bronze1man/kmg/kmgTime" 14 ) 15 16 /* 17 try best transform one type to another type 18 special case: 19 "" => 0 20 "" => 0.0 21 */ 22 func Transform(in interface{}, out interface{}) (err error) { 23 return DefaultTransformer.Transform(in, out) 24 } 25 26 func MustTransform(in interface{}, out interface{}) { 27 err := DefaultTransformer.Transform(in, out) 28 if err != nil { 29 panic(err) 30 } 31 } 32 33 func MustTransformToMap(in interface{}) (m map[string]string) { 34 m = map[string]string{} 35 err := DefaultTransformer.Transform(in, &m) 36 if err != nil { 37 panic(err) 38 } 39 return m 40 } 41 42 func MapToMap(t Transformer, in reflect.Value, out reflect.Value) (err error) { 43 out.Set(reflect.MakeMap(out.Type())) 44 for _, key := range in.MapKeys() { 45 oKey := reflect.New(out.Type().Key()).Elem() 46 oVal := reflect.New(out.Type().Elem()).Elem() 47 err = t.Tran(key, oKey) 48 if err != nil { 49 return 50 } 51 val := in.MapIndex(key) 52 err = t.Tran(val, oVal) 53 if err != nil { 54 return 55 } 56 out.SetMapIndex(oKey, oVal) 57 } 58 return 59 } 60 61 func StringToString(t Transformer, in reflect.Value, out reflect.Value) (err error) { 62 out.SetString(in.String()) 63 return nil 64 } 65 66 func NewStringToTimeFunc(location *time.Location) TransformerFunc { 67 return func(traner Transformer, in reflect.Value, out reflect.Value) (err error) { 68 var t time.Time 69 t, err = kmgTime.ParseAutoInLocation(in.String(), location) 70 if err != nil { 71 return 72 } 73 out.Set(reflect.ValueOf(t)) 74 return 75 } 76 } 77 78 func StringToTime(traner Transformer, in reflect.Value, out reflect.Value) (err error) { 79 var t time.Time 80 t, err = kmgTime.ParseAutoInLocal(in.String()) 81 if err != nil { 82 return 83 } 84 out.Set(reflect.ValueOf(t)) 85 return 86 } 87 88 func TimeToString(traner Transformer, in reflect.Value, out reflect.Value) (err error) { 89 t := in.Interface().(time.Time) 90 out.SetString(t.In(kmgTime.DefaultTimeZone).Format(kmgTime.FormatMysql)) 91 return nil 92 } 93 94 func PtrToPtr(t Transformer, in reflect.Value, out reflect.Value) (err error) { 95 return t.Tran(in.Elem(), out.Elem()) 96 } 97 98 //假设map的key类型是string,值类型不限 99 func MapToStruct(t Transformer, in reflect.Value, out reflect.Value) (err error) { 100 oKey := reflect.New(reflect.TypeOf("")).Elem() 101 out.Set(reflect.New(out.Type()).Elem()) 102 fieldNameMap := map[string]bool{} 103 for _, key := range in.MapKeys() { 104 err = t.Tran(key, oKey) 105 if err != nil { 106 return 107 } 108 sKey := oKey.String() 109 fieldNameMap[sKey] = true 110 oVal := out.FieldByName(sKey) 111 if !oVal.IsValid() { 112 continue 113 } 114 val := in.MapIndex(key) 115 err = t.Tran(val, oVal) 116 if err != nil { 117 return 118 } 119 } 120 return 121 } 122 123 //假设map的key类型是string,值类型不限 124 func StructToMap(t Transformer, in reflect.Value, out reflect.Value) (err error) { 125 oValType := out.Type().Elem() 126 oKey := reflect.New(reflect.TypeOf("")).Elem() 127 if out.IsNil() { 128 out.Set(reflect.MakeMap(out.Type())) //新建map不能使用reflect.New 129 } 130 131 fieldMap := kmgReflect.StructGetAllFieldMap(in.Type()) 132 for key, field := range fieldMap { 133 if field.PkgPath != "" { 134 //忽略没有导出的字段 135 continue 136 } 137 iVal := in.FieldByName(key) 138 oVal := reflect.New(oValType).Elem() 139 err = t.Tran(iVal, oVal) 140 if err != nil { 141 return 142 } 143 oKey.SetString(key) 144 out.SetMapIndex(oKey, oVal) 145 } 146 return nil 147 } 148 149 func SliceToSlice(t Transformer, in reflect.Value, out reflect.Value) (err error) { 150 len := in.Len() 151 out.Set(reflect.MakeSlice(out.Type(), len, len)) 152 for i := 0; i < len; i++ { 153 val := in.Index(i) 154 err = t.Tran(val, out.Index(i)) 155 if err != nil { 156 return 157 } 158 } 159 return 160 } 161 162 // "" => 0 163 func StringToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) { 164 inS := in.String() 165 inS = strings.TrimSpace(inS) 166 if inS == "" { 167 out.SetInt(int64(0)) 168 return nil 169 } 170 i, err := strconv.ParseInt(inS, 10, out.Type().Bits()) 171 if err != nil { 172 return 173 } 174 out.SetInt(i) 175 return 176 } 177 178 // "" => 0 179 func StringToUint(t Transformer, in reflect.Value, out reflect.Value) (err error) { 180 inS := in.String() 181 inS = strings.TrimSpace(inS) 182 if inS == "" { 183 out.SetUint(uint64(0)) 184 return nil 185 } 186 i, err := strconv.ParseUint(inS, 10, out.Type().Bits()) 187 if err != nil { 188 return 189 } 190 out.SetUint(i) 191 return 192 } 193 194 // "" => 0.0 195 func StringToFloat(t Transformer, in reflect.Value, out reflect.Value) (err error) { 196 inS := in.String() 197 if inS == "" { 198 out.SetFloat(0.0) 199 return nil 200 } 201 i, err := strconv.ParseFloat(inS, out.Type().Bits()) 202 if err != nil { 203 return 204 } 205 out.SetFloat(i) 206 return 207 } 208 209 // "" => false 210 func StringToBool(t Transformer, in reflect.Value, out reflect.Value) (err error) { 211 inS := in.String() 212 if inS == "" { 213 out.SetBool(false) 214 return nil 215 } 216 i, err := strconv.ParseBool(inS) 217 if err != nil { 218 return 219 } 220 out.SetBool(i) 221 return 222 } 223 224 func IntToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) { 225 out.SetInt(in.Int()) 226 return nil 227 } 228 229 func FloatToInt(t Transformer, in reflect.Value, out reflect.Value) (err error) { 230 outf1 := in.Float() 231 if math.Floor(outf1) != outf1 { 232 return fmt.Errorf("[typeTransform.tran] it seems to lose some accuracy trying to convert from float to int,float:%f", outf1) 233 } 234 out.SetInt(int64(outf1)) 235 return 236 } 237 238 func FloatToFloat(t Transformer, in reflect.Value, out reflect.Value) (err error) { 239 out.SetFloat(in.Float()) 240 return 241 } 242 243 func FloatToString(t Transformer, in reflect.Value, out reflect.Value) (err error) { 244 f := in.Float() 245 fs := kmgStrconv.FormatFloat(f) 246 out.SetString(fs) 247 return 248 } 249 250 func NonePtrToPtr(t Transformer, in reflect.Value, out reflect.Value) (err error) { 251 if out.IsNil() { 252 out.Set(reflect.New(out.Type().Elem())) 253 } 254 return t.Tran(in, out.Elem()) 255 } 256 func InterfaceToNoneInterface(t Transformer, in reflect.Value, out reflect.Value) (err error) { 257 return t.Tran(in.Elem(), out) 258 } 259 func NoneInterfaceToInterface(t Transformer, in reflect.Value, out reflect.Value) (err error) { 260 //满足interface的情况 261 if in.Type().Implements(out.Type()) { 262 out.Set(in) 263 return 264 } 265 return t.Tran(in, out.Elem()) 266 } 267 268 func IntToString(t Transformer, in reflect.Value, out reflect.Value) (err error) { 269 s := strconv.FormatInt(in.Int(), 10) 270 out.SetString(s) 271 return nil 272 }