@@ -27,13 +27,19 @@ var (
27
27
// (numeric) but the Struct field was a non numeric type (i.e. not int, uint,
28
28
// float, etc)
29
29
ErrUnknownFieldNumberType = errors .New ("The struct field was not of a known number type" )
30
- // ErrUnsupportedPtrType is returned when the Struct field was a pointer but
31
- // the JSON value was of a different type
32
- ErrUnsupportedPtrType = errors .New ("Pointer type in struct is not supported" )
33
30
// ErrInvalidType is returned when the given type is incompatible with the expected type.
34
31
ErrInvalidType = errors .New ("Invalid type provided" ) // I wish we used punctuation.
35
32
)
36
33
34
+ // ErrUnsupportedPtrType is returned when the Struct field was a pointer but
35
+ // the JSON value was of a different type
36
+ func ErrUnsupportedPtrType (rf reflect.Value , f reflect.Type , structField reflect.StructField ) error {
37
+ return fmt .Errorf (
38
+ "[jsonapi unmarshalNode]: Can't unmarshal %+v (%s) to struct field `%s`, which is a pointer to `%s` (%s), which is not a supported type" ,
39
+ rf , rf .Type ().Name (), structField .Name , f .Elem ().Name (), f .Elem ().Kind (),
40
+ )
41
+ }
42
+
37
43
// UnmarshalPayload converts an io into a struct instance using jsonapi tags on
38
44
// struct fields. This method supports single request payloads only, at the
39
45
// moment. Bulk creates and updates are not supported yet.
@@ -256,7 +262,8 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
256
262
continue
257
263
}
258
264
259
- value , err := unmarshalAttribute (attribute , args , fieldType .Type , fieldValue )
265
+ structField := fieldType
266
+ value , err := unmarshalAttribute (attribute , args , structField , fieldValue )
260
267
if err != nil {
261
268
er = err
262
269
break
@@ -363,9 +370,10 @@ func assign(field, value reflect.Value) {
363
370
}
364
371
}
365
372
366
- func unmarshalAttribute (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (value reflect.Value , err error ) {
373
+ func unmarshalAttribute (attribute interface {}, args []string , structField reflect.StructField , fieldValue reflect.Value ) (value reflect.Value , err error ) {
367
374
368
375
value = reflect .ValueOf (attribute )
376
+ fieldType := structField .Type
369
377
370
378
// Handle field of type []string
371
379
if fieldValue .Type () == reflect .TypeOf ([]string {}) {
@@ -399,7 +407,7 @@ func unmarshalAttribute(attribute interface{}, args []string, fieldType reflect.
399
407
400
408
// Field was a Pointer type
401
409
if fieldValue .Kind () == reflect .Ptr {
402
- value , err = handlePointer (attribute , args , fieldType , fieldValue )
410
+ value , err = handlePointer (attribute , args , fieldType , fieldValue , structField )
403
411
return
404
412
}
405
413
@@ -527,7 +535,7 @@ func handleNumeric(attribute interface{}, args []string, fieldType reflect.Type,
527
535
return numericValue , nil
528
536
}
529
537
530
- func handlePointer (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
538
+ func handlePointer (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value , structField reflect. StructField ) (reflect.Value , error ) {
531
539
t := fieldValue .Type ()
532
540
var concreteVal reflect.Value
533
541
@@ -543,11 +551,11 @@ func handlePointer(attribute interface{}, args []string, fieldType reflect.Type,
543
551
case uintptr :
544
552
concreteVal = reflect .ValueOf (& cVal )
545
553
default :
546
- return reflect.Value {}, ErrUnsupportedPtrType
554
+ return reflect.Value {}, ErrUnsupportedPtrType ( reflect . ValueOf ( attribute ), fieldType , structField )
547
555
}
548
556
549
557
if t != concreteVal .Type () {
550
- return reflect.Value {}, ErrUnsupportedPtrType
558
+ return reflect.Value {}, ErrUnsupportedPtrType ( reflect . ValueOf ( attribute ), fieldType , structField )
551
559
}
552
560
553
561
return concreteVal , nil
0 commit comments