1 package decoder
2
3 import (
4 "fmt"
5 "reflect"
6 "strconv"
7 )
8
9 var (
10 nilValue = reflect.ValueOf(nil)
11 )
12
13 func AssignValue(src, dst reflect.Value) error {
14 if dst.Type().Kind() != reflect.Ptr {
15 return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type())
16 }
17 casted, err := castValue(dst.Elem().Type(), src)
18 if err != nil {
19 return err
20 }
21 dst.Elem().Set(casted)
22 return nil
23 }
24
25 func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) {
26 switch t.Kind() {
27 case reflect.Int:
28 vv, err := castInt(v)
29 if err != nil {
30 return nilValue, err
31 }
32 return reflect.ValueOf(int(vv.Int())), nil
33 case reflect.Int8:
34 vv, err := castInt(v)
35 if err != nil {
36 return nilValue, err
37 }
38 return reflect.ValueOf(int8(vv.Int())), nil
39 case reflect.Int16:
40 vv, err := castInt(v)
41 if err != nil {
42 return nilValue, err
43 }
44 return reflect.ValueOf(int16(vv.Int())), nil
45 case reflect.Int32:
46 vv, err := castInt(v)
47 if err != nil {
48 return nilValue, err
49 }
50 return reflect.ValueOf(int32(vv.Int())), nil
51 case reflect.Int64:
52 return castInt(v)
53 case reflect.Uint:
54 vv, err := castUint(v)
55 if err != nil {
56 return nilValue, err
57 }
58 return reflect.ValueOf(uint(vv.Uint())), nil
59 case reflect.Uint8:
60 vv, err := castUint(v)
61 if err != nil {
62 return nilValue, err
63 }
64 return reflect.ValueOf(uint8(vv.Uint())), nil
65 case reflect.Uint16:
66 vv, err := castUint(v)
67 if err != nil {
68 return nilValue, err
69 }
70 return reflect.ValueOf(uint16(vv.Uint())), nil
71 case reflect.Uint32:
72 vv, err := castUint(v)
73 if err != nil {
74 return nilValue, err
75 }
76 return reflect.ValueOf(uint32(vv.Uint())), nil
77 case reflect.Uint64:
78 return castUint(v)
79 case reflect.Uintptr:
80 vv, err := castUint(v)
81 if err != nil {
82 return nilValue, err
83 }
84 return reflect.ValueOf(uintptr(vv.Uint())), nil
85 case reflect.String:
86 return castString(v)
87 case reflect.Bool:
88 return castBool(v)
89 case reflect.Float32:
90 vv, err := castFloat(v)
91 if err != nil {
92 return nilValue, err
93 }
94 return reflect.ValueOf(float32(vv.Float())), nil
95 case reflect.Float64:
96 return castFloat(v)
97 case reflect.Array:
98 return castArray(t, v)
99 case reflect.Slice:
100 return castSlice(t, v)
101 case reflect.Map:
102 return castMap(t, v)
103 case reflect.Struct:
104 return castStruct(t, v)
105 }
106 return v, nil
107 }
108
109 func castInt(v reflect.Value) (reflect.Value, error) {
110 switch v.Type().Kind() {
111 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
112 return v, nil
113 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
114 return reflect.ValueOf(int64(v.Uint())), nil
115 case reflect.String:
116 i64, err := strconv.ParseInt(v.String(), 10, 64)
117 if err != nil {
118 return nilValue, err
119 }
120 return reflect.ValueOf(i64), nil
121 case reflect.Bool:
122 if v.Bool() {
123 return reflect.ValueOf(int64(1)), nil
124 }
125 return reflect.ValueOf(int64(0)), nil
126 case reflect.Float32, reflect.Float64:
127 return reflect.ValueOf(int64(v.Float())), nil
128 case reflect.Array:
129 if v.Len() > 0 {
130 return castInt(v.Index(0))
131 }
132 return nilValue, fmt.Errorf("failed to cast to int64 from empty array")
133 case reflect.Slice:
134 if v.Len() > 0 {
135 return castInt(v.Index(0))
136 }
137 return nilValue, fmt.Errorf("failed to cast to int64 from empty slice")
138 case reflect.Interface:
139 return castInt(reflect.ValueOf(v.Interface()))
140 case reflect.Map:
141 return nilValue, fmt.Errorf("failed to cast to int64 from map")
142 case reflect.Struct:
143 return nilValue, fmt.Errorf("failed to cast to int64 from struct")
144 case reflect.Ptr:
145 return castInt(v.Elem())
146 }
147 return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind())
148 }
149
150 func castUint(v reflect.Value) (reflect.Value, error) {
151 switch v.Type().Kind() {
152 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
153 return reflect.ValueOf(uint64(v.Int())), nil
154 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
155 return v, nil
156 case reflect.String:
157 u64, err := strconv.ParseUint(v.String(), 10, 64)
158 if err != nil {
159 return nilValue, err
160 }
161 return reflect.ValueOf(u64), nil
162 case reflect.Bool:
163 if v.Bool() {
164 return reflect.ValueOf(uint64(1)), nil
165 }
166 return reflect.ValueOf(uint64(0)), nil
167 case reflect.Float32, reflect.Float64:
168 return reflect.ValueOf(uint64(v.Float())), nil
169 case reflect.Array:
170 if v.Len() > 0 {
171 return castUint(v.Index(0))
172 }
173 return nilValue, fmt.Errorf("failed to cast to uint64 from empty array")
174 case reflect.Slice:
175 if v.Len() > 0 {
176 return castUint(v.Index(0))
177 }
178 return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice")
179 case reflect.Interface:
180 return castUint(reflect.ValueOf(v.Interface()))
181 case reflect.Map:
182 return nilValue, fmt.Errorf("failed to cast to uint64 from map")
183 case reflect.Struct:
184 return nilValue, fmt.Errorf("failed to cast to uint64 from struct")
185 case reflect.Ptr:
186 return castUint(v.Elem())
187 }
188 return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind())
189 }
190
191 func castString(v reflect.Value) (reflect.Value, error) {
192 switch v.Type().Kind() {
193 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
194 return reflect.ValueOf(fmt.Sprint(v.Int())), nil
195 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
196 return reflect.ValueOf(fmt.Sprint(v.Uint())), nil
197 case reflect.String:
198 return v, nil
199 case reflect.Bool:
200 if v.Bool() {
201 return reflect.ValueOf("true"), nil
202 }
203 return reflect.ValueOf("false"), nil
204 case reflect.Float32, reflect.Float64:
205 return reflect.ValueOf(fmt.Sprint(v.Float())), nil
206 case reflect.Array:
207 if v.Len() > 0 {
208 return castString(v.Index(0))
209 }
210 return nilValue, fmt.Errorf("failed to cast to string from empty array")
211 case reflect.Slice:
212 if v.Len() > 0 {
213 return castString(v.Index(0))
214 }
215 return nilValue, fmt.Errorf("failed to cast to string from empty slice")
216 case reflect.Interface:
217 return castString(reflect.ValueOf(v.Interface()))
218 case reflect.Map:
219 return nilValue, fmt.Errorf("failed to cast to string from map")
220 case reflect.Struct:
221 return nilValue, fmt.Errorf("failed to cast to string from struct")
222 case reflect.Ptr:
223 return castString(v.Elem())
224 }
225 return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind())
226 }
227
228 func castBool(v reflect.Value) (reflect.Value, error) {
229 switch v.Type().Kind() {
230 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
231 switch v.Int() {
232 case 0:
233 return reflect.ValueOf(false), nil
234 case 1:
235 return reflect.ValueOf(true), nil
236 }
237 return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int())
238 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
239 switch v.Uint() {
240 case 0:
241 return reflect.ValueOf(false), nil
242 case 1:
243 return reflect.ValueOf(true), nil
244 }
245 return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint())
246 case reflect.String:
247 b, err := strconv.ParseBool(v.String())
248 if err != nil {
249 return nilValue, err
250 }
251 return reflect.ValueOf(b), nil
252 case reflect.Bool:
253 return v, nil
254 case reflect.Float32, reflect.Float64:
255 switch v.Float() {
256 case 0:
257 return reflect.ValueOf(false), nil
258 case 1:
259 return reflect.ValueOf(true), nil
260 }
261 return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float())
262 case reflect.Array:
263 if v.Len() > 0 {
264 return castBool(v.Index(0))
265 }
266 return nilValue, fmt.Errorf("failed to cast to string from empty array")
267 case reflect.Slice:
268 if v.Len() > 0 {
269 return castBool(v.Index(0))
270 }
271 return nilValue, fmt.Errorf("failed to cast to string from empty slice")
272 case reflect.Interface:
273 return castBool(reflect.ValueOf(v.Interface()))
274 case reflect.Map:
275 return nilValue, fmt.Errorf("failed to cast to string from map")
276 case reflect.Struct:
277 return nilValue, fmt.Errorf("failed to cast to string from struct")
278 case reflect.Ptr:
279 return castBool(v.Elem())
280 }
281 return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind())
282 }
283
284 func castFloat(v reflect.Value) (reflect.Value, error) {
285 switch v.Type().Kind() {
286 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
287 return reflect.ValueOf(float64(v.Int())), nil
288 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
289 return reflect.ValueOf(float64(v.Uint())), nil
290 case reflect.String:
291 f64, err := strconv.ParseFloat(v.String(), 64)
292 if err != nil {
293 return nilValue, err
294 }
295 return reflect.ValueOf(f64), nil
296 case reflect.Bool:
297 if v.Bool() {
298 return reflect.ValueOf(float64(1)), nil
299 }
300 return reflect.ValueOf(float64(0)), nil
301 case reflect.Float32, reflect.Float64:
302 return v, nil
303 case reflect.Array:
304 if v.Len() > 0 {
305 return castFloat(v.Index(0))
306 }
307 return nilValue, fmt.Errorf("failed to cast to float64 from empty array")
308 case reflect.Slice:
309 if v.Len() > 0 {
310 return castFloat(v.Index(0))
311 }
312 return nilValue, fmt.Errorf("failed to cast to float64 from empty slice")
313 case reflect.Interface:
314 return castFloat(reflect.ValueOf(v.Interface()))
315 case reflect.Map:
316 return nilValue, fmt.Errorf("failed to cast to float64 from map")
317 case reflect.Struct:
318 return nilValue, fmt.Errorf("failed to cast to float64 from struct")
319 case reflect.Ptr:
320 return castFloat(v.Elem())
321 }
322 return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind())
323 }
324
325 func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) {
326 kind := v.Type().Kind()
327 if kind == reflect.Interface {
328 return castArray(t, reflect.ValueOf(v.Interface()))
329 }
330 if kind != reflect.Slice && kind != reflect.Array {
331 return nilValue, fmt.Errorf("failed to cast to array from %s", kind)
332 }
333 if t.Elem() == v.Type().Elem() {
334 return v, nil
335 }
336 if t.Len() != v.Len() {
337 return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len())
338 }
339 ret := reflect.New(t).Elem()
340 for i := 0; i < v.Len(); i++ {
341 vv, err := castValue(t.Elem(), v.Index(i))
342 if err != nil {
343 return nilValue, err
344 }
345 ret.Index(i).Set(vv)
346 }
347 return ret, nil
348 }
349
350 func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) {
351 kind := v.Type().Kind()
352 if kind == reflect.Interface {
353 return castSlice(t, reflect.ValueOf(v.Interface()))
354 }
355 if kind != reflect.Slice && kind != reflect.Array {
356 return nilValue, fmt.Errorf("failed to cast to slice from %s", kind)
357 }
358 if t.Elem() == v.Type().Elem() {
359 return v, nil
360 }
361 ret := reflect.MakeSlice(t, v.Len(), v.Len())
362 for i := 0; i < v.Len(); i++ {
363 vv, err := castValue(t.Elem(), v.Index(i))
364 if err != nil {
365 return nilValue, err
366 }
367 ret.Index(i).Set(vv)
368 }
369 return ret, nil
370 }
371
372 func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) {
373 ret := reflect.MakeMap(t)
374 switch v.Type().Kind() {
375 case reflect.Map:
376 iter := v.MapRange()
377 for iter.Next() {
378 key, err := castValue(t.Key(), iter.Key())
379 if err != nil {
380 return nilValue, err
381 }
382 value, err := castValue(t.Elem(), iter.Value())
383 if err != nil {
384 return nilValue, err
385 }
386 ret.SetMapIndex(key, value)
387 }
388 return ret, nil
389 case reflect.Interface:
390 return castMap(t, reflect.ValueOf(v.Interface()))
391 case reflect.Slice:
392 if v.Len() > 0 {
393 return castMap(t, v.Index(0))
394 }
395 return nilValue, fmt.Errorf("failed to cast to map from empty slice")
396 }
397 return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind())
398 }
399
400 func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) {
401 ret := reflect.New(t).Elem()
402 switch v.Type().Kind() {
403 case reflect.Map:
404 iter := v.MapRange()
405 for iter.Next() {
406 key := iter.Key()
407 k, err := castString(key)
408 if err != nil {
409 return nilValue, err
410 }
411 fieldName := k.String()
412 field, ok := t.FieldByName(fieldName)
413 if ok {
414 value, err := castValue(field.Type, iter.Value())
415 if err != nil {
416 return nilValue, err
417 }
418 ret.FieldByName(fieldName).Set(value)
419 }
420 }
421 return ret, nil
422 case reflect.Struct:
423 for i := 0; i < v.Type().NumField(); i++ {
424 name := v.Type().Field(i).Name
425 ret.FieldByName(name).Set(v.FieldByName(name))
426 }
427 return ret, nil
428 case reflect.Interface:
429 return castStruct(t, reflect.ValueOf(v.Interface()))
430 case reflect.Slice:
431 if v.Len() > 0 {
432 return castStruct(t, v.Index(0))
433 }
434 return nilValue, fmt.Errorf("failed to cast to struct from empty slice")
435 default:
436 return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind())
437 }
438 }
439
View as plain text