@@ -29,22 +29,33 @@ var (
2929 ErrUnknownFieldNumberType = errors .New ("The struct field was not of a known number type" )
3030 // ErrInvalidType is returned when the given type is incompatible with the expected type.
3131 ErrInvalidType = errors .New ("Invalid type provided" ) // I wish we used punctuation.
32+
3233)
3334
3435// ErrUnsupportedPtrType is returned when the Struct field was a pointer but
3536// the JSON value was of a different type
36- func ErrUnsupportedPtrType (rf reflect.Value , t reflect.Type , structField reflect.StructField ) error {
37- typeName := t .Elem ().Name ()
38- kind := t .Elem ().Kind ()
37+ type ErrUnsupportedPtrType struct {
38+ rf reflect.Value
39+ t reflect.Type
40+ structField reflect.StructField
41+ }
42+
43+ func (eupt ErrUnsupportedPtrType ) Error () string {
44+ typeName := eupt .t .Elem ().Name ()
45+ kind := eupt .t .Elem ().Kind ()
3946 if kind .String () != "" && kind .String () != typeName {
4047 typeName = fmt .Sprintf ("%s (%s)" , typeName , kind .String ())
4148 }
42- return fmt .Errorf (
49+ return fmt .Sprintf (
4350 "jsonapi: Can't unmarshal %+v (%s) to struct field `%s`, which is a pointer to `%s`" ,
44- rf , rf .Type ().Kind (), structField .Name , typeName ,
51+ eupt . rf , eupt . rf .Type ().Kind (), eupt . structField .Name , typeName ,
4552 )
4653}
4754
55+ func newErrUnsupportedPtrType (rf reflect.Value , t reflect.Type , structField reflect.StructField ) error {
56+ return ErrUnsupportedPtrType {rf , t , structField }
57+ }
58+
4859// UnmarshalPayload converts an io into a struct instance using jsonapi tags on
4960// struct fields. This method supports single request payloads only, at the
5061// moment. Bulk creates and updates are not supported yet.
@@ -129,7 +140,6 @@ func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) {
129140}
130141
131142func unmarshalNode (data * Node , model reflect.Value , included * map [string ]* Node ) (err error ) {
132-
133143 defer func () {
134144 if r := recover (); r != nil {
135145 err = fmt .Errorf ("data is not a jsonapi representation of '%v'" , model .Type ())
@@ -375,8 +385,11 @@ func assign(field, value reflect.Value) {
375385 }
376386}
377387
378- func unmarshalAttribute (attribute interface {}, args []string , structField reflect.StructField , fieldValue reflect.Value ) (value reflect.Value , err error ) {
379-
388+ func unmarshalAttribute (
389+ attribute interface {},
390+ args []string ,
391+ structField reflect.StructField ,
392+ fieldValue reflect.Value ) (value reflect.Value , err error ) {
380393 value = reflect .ValueOf (attribute )
381394 fieldType := structField .Type
382395
@@ -387,7 +400,8 @@ func unmarshalAttribute(attribute interface{}, args []string, structField reflec
387400 }
388401
389402 // Handle field of type time.Time
390- if fieldValue .Type () == reflect .TypeOf (time.Time {}) || fieldValue .Type () == reflect .TypeOf (new (time.Time )) {
403+ if fieldValue .Type () == reflect .TypeOf (time.Time {}) ||
404+ fieldValue .Type () == reflect .TypeOf (new (time.Time )) {
391405 value , err = handleTime (attribute , args , fieldType , fieldValue )
392406 return
393407 }
@@ -399,7 +413,8 @@ func unmarshalAttribute(attribute interface{}, args []string, structField reflec
399413 }
400414
401415 // Handle field containing slice of structs
402- if fieldValue .Type ().Kind () == reflect .Slice && reflect .TypeOf (fieldValue .Interface ()).Elem ().Kind () == reflect .Struct {
416+ if fieldValue .Type ().Kind () == reflect .Slice &&
417+ reflect .TypeOf (fieldValue .Interface ()).Elem ().Kind () == reflect .Struct {
403418 value , err = handleStructSlice (attribute , args , fieldType , fieldValue )
404419 return
405420 }
@@ -425,7 +440,11 @@ func unmarshalAttribute(attribute interface{}, args []string, structField reflec
425440 return
426441}
427442
428- func handleStringSlice (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
443+ func handleStringSlice (
444+ attribute interface {},
445+ args []string ,
446+ fieldType reflect.Type ,
447+ fieldValue reflect.Value ) (reflect.Value , error ) {
429448 v := reflect .ValueOf (attribute )
430449 values := make ([]string , v .Len ())
431450 for i := 0 ; i < v .Len (); i ++ {
@@ -435,8 +454,11 @@ func handleStringSlice(attribute interface{}, args []string, fieldType reflect.T
435454 return reflect .ValueOf (values ), nil
436455}
437456
438- func handleTime (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
439-
457+ func handleTime (
458+ attribute interface {},
459+ args []string ,
460+ fieldType reflect.Type ,
461+ fieldValue reflect.Value ) (reflect.Value , error ) {
440462 var isIso8601 bool
441463 v := reflect .ValueOf (attribute )
442464
@@ -483,7 +505,11 @@ func handleTime(attribute interface{}, args []string, fieldType reflect.Type, fi
483505 return reflect .ValueOf (t ), nil
484506}
485507
486- func handleNumeric (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
508+ func handleNumeric (
509+ attribute interface {},
510+ args []string ,
511+ fieldType reflect.Type ,
512+ fieldValue reflect.Value ) (reflect.Value , error ) {
487513 v := reflect .ValueOf (attribute )
488514 floatValue := v .Interface ().(float64 )
489515
@@ -540,7 +566,12 @@ func handleNumeric(attribute interface{}, args []string, fieldType reflect.Type,
540566 return numericValue , nil
541567}
542568
543- func handlePointer (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value , structField reflect.StructField ) (reflect.Value , error ) {
569+ func handlePointer (
570+ attribute interface {},
571+ args []string ,
572+ fieldType reflect.Type ,
573+ fieldValue reflect.Value ,
574+ structField reflect.StructField ) (reflect.Value , error ) {
544575 t := fieldValue .Type ()
545576 var concreteVal reflect.Value
546577
@@ -549,50 +580,55 @@ func handlePointer(attribute interface{}, args []string, fieldType reflect.Type,
549580 concreteVal = reflect .ValueOf (& cVal )
550581 case bool :
551582 concreteVal = reflect .ValueOf (& cVal )
552- case complex64 :
553- concreteVal = reflect .ValueOf (& cVal )
554- case complex128 :
555- concreteVal = reflect .ValueOf (& cVal )
556- case uintptr :
583+ case complex64 , complex128 , uintptr :
557584 concreteVal = reflect .ValueOf (& cVal )
558585 case map [string ]interface {}:
559586 var err error
560587 concreteVal , err = handleStruct (attribute , args , fieldType , fieldValue )
561588 if err != nil {
562- return reflect.Value {}, ErrUnsupportedPtrType (reflect .ValueOf (attribute ), fieldType , structField )
589+ return reflect.Value {}, newErrUnsupportedPtrType (
590+ reflect .ValueOf (attribute ), fieldType , structField )
563591 }
564592 return concreteVal .Elem (), err
565593 default :
566- return reflect.Value {}, ErrUnsupportedPtrType (reflect .ValueOf (attribute ), fieldType , structField )
594+ return reflect.Value {}, newErrUnsupportedPtrType (
595+ reflect .ValueOf (attribute ), fieldType , structField )
567596 }
568597
569598 if t != concreteVal .Type () {
570- return reflect.Value {}, ErrUnsupportedPtrType (reflect .ValueOf (attribute ), fieldType , structField )
599+ return reflect.Value {}, newErrUnsupportedPtrType (
600+ reflect .ValueOf (attribute ), fieldType , structField )
571601 }
572602
573603 return concreteVal , nil
574604}
575605
576- func handleStruct (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
606+ func handleStruct (
607+ attribute interface {},
608+ args []string ,
609+ fieldType reflect.Type ,
610+ fieldValue reflect.Value ) (reflect.Value , error ) {
577611 model := reflect .New (fieldValue .Type ())
578612
579- var er error
580-
581- data , er := json .Marshal (attribute )
582- if er != nil {
583- return model , er
613+ data , err := json .Marshal (attribute )
614+ if err != nil {
615+ return model , err
584616 }
585617
586- er = json .Unmarshal (data , model .Interface ())
618+ err = json .Unmarshal (data , model .Interface ())
587619
588- if er != nil {
589- return model , er
620+ if err != nil {
621+ return model , err
590622 }
591623
592- return model , er
624+ return model , err
593625}
594626
595- func handleStructSlice (attribute interface {}, args []string , fieldType reflect.Type , fieldValue reflect.Value ) (reflect.Value , error ) {
627+ func handleStructSlice (
628+ attribute interface {},
629+ args []string ,
630+ fieldType reflect.Type ,
631+ fieldValue reflect.Value ) (reflect.Value , error ) {
596632 models := reflect .New (fieldValue .Type ()).Elem ()
597633 dataMap := reflect .ValueOf (attribute ).Interface ().([]interface {})
598634 for _ , data := range dataMap {
0 commit comments