@@ -60,11 +60,6 @@ func newErrUnsupportedPtrType(rf reflect.Value, t reflect.Type, structField refl
6060 return ErrUnsupportedPtrType {rf , t , structField }
6161}
6262
63- type includedNode struct {
64- node * Node
65- model * reflect.Value
66- }
67-
6863// UnmarshalPayload converts an io into a struct instance using jsonapi tags on
6964// struct fields. This method supports single request payloads only, at the
7065// moment. Bulk creates and updates are not supported yet.
@@ -99,19 +94,19 @@ type includedNode struct {
9994// model interface{} should be a pointer to a struct.
10095func UnmarshalPayload (in io.Reader , model interface {}) error {
10196 payload := new (OnePayload )
102- included := make (map [string ]* includedNode )
10397
10498 if err := json .NewDecoder (in ).Decode (payload ); err != nil {
10599 return err
106100 }
107101
108102 if payload .Included != nil {
109- for _ , include := range payload .Included {
110- key := fmt .Sprintf ("%s,%s" , include .Type , include .ID )
111- included [key ] = & includedNode {include , nil }
103+ includedMap := make (map [string ]* Node )
104+ for _ , included := range payload .Included {
105+ key := fmt .Sprintf ("%s,%s" , included .Type , included .ID )
106+ includedMap [key ] = included
112107 }
113108
114- return unmarshalNode (payload .Data , reflect .ValueOf (model ), & included )
109+ return unmarshalNode (payload .Data , reflect .ValueOf (model ), & includedMap )
115110 }
116111 return unmarshalNode (payload .Data , reflect .ValueOf (model ), nil )
117112}
@@ -125,19 +120,19 @@ func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) {
125120 return nil , err
126121 }
127122
128- models := []interface {}{} // will be populated from the "data"
129- included := map [string ]* includedNode {} // will be populate from the "included"
123+ models := []interface {}{} // will be populated from the "data"
124+ includedMap := map [string ]* Node {} // will be populate from the "included"
130125
131126 if payload .Included != nil {
132- for _ , include := range payload .Included {
133- key := fmt .Sprintf ("%s,%s" , include .Type , include .ID )
134- included [key ] = & includedNode { include , nil }
127+ for _ , included := range payload .Included {
128+ key := fmt .Sprintf ("%s,%s" , included .Type , included .ID )
129+ includedMap [key ] = included
135130 }
136131 }
137132
138133 for _ , data := range payload .Data {
139134 model := reflect .New (t .Elem ())
140- err := unmarshalNode (data , model , & included )
135+ err := unmarshalNode (data , model , & includedMap )
141136 if err != nil {
142137 return nil , err
143138 }
@@ -268,7 +263,7 @@ func getStructTags(field reflect.StructField) ([]string, error) {
268263
269264// unmarshalNodeMaybeChoice populates a model that may or may not be
270265// a choice type struct that corresponds to a polyrelation or relation
271- func unmarshalNodeMaybeChoice (m * reflect.Value , data * Node , annotation string , choiceTypeMapping map [string ]structFieldIndex , included * map [string ]* includedNode ) error {
266+ func unmarshalNodeMaybeChoice (m * reflect.Value , data * Node , annotation string , choiceTypeMapping map [string ]structFieldIndex , included * map [string ]* Node ) error {
272267 // This will hold either the value of the choice type model or the actual
273268 // model, depending on annotation
274269 var actualModel = * m
@@ -305,7 +300,7 @@ func unmarshalNodeMaybeChoice(m *reflect.Value, data *Node, annotation string, c
305300 return nil
306301}
307302
308- func unmarshalNode (data * Node , model reflect.Value , included * map [string ]* includedNode ) (err error ) {
303+ func unmarshalNode (data * Node , model reflect.Value , included * map [string ]* Node ) (err error ) {
309304 defer func () {
310305 if r := recover (); r != nil {
311306 err = fmt .Errorf ("data is not a jsonapi representation of '%v'" , model .Type ())
@@ -534,23 +529,6 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*includ
534529 continue
535530 }
536531
537- // Check if the item in the relationship was already processed elsewhere. Avoids potential infinite recursive loops
538- // caused by circular references between included relationships (two included items include one another)
539- includedKey := fmt .Sprintf ("%s,%s" , relationship .Data .Type , relationship .Data .ID )
540- if included != nil && (* included )[includedKey ] != nil {
541- if (* included )[includedKey ].model != nil {
542- fieldValue .Set (* (* included )[includedKey ].model )
543- } else {
544- (* included )[includedKey ].model = & m
545- err := unmarshalNodeMaybeChoice (& m , (* included )[includedKey ].node , annotation , choiceMapping , included )
546- if err != nil {
547- er = err
548- break
549- }
550- fieldValue .Set (m )
551- }
552- continue
553- }
554532 err = unmarshalNodeMaybeChoice (& m , relationship .Data , annotation , choiceMapping , included )
555533 if err != nil {
556534 er = err
@@ -612,11 +590,11 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*includ
612590 return er
613591}
614592
615- func fullNode (n * Node , included * map [string ]* includedNode ) * Node {
593+ func fullNode (n * Node , included * map [string ]* Node ) * Node {
616594 includedKey := fmt .Sprintf ("%s,%s" , n .Type , n .ID )
617595
618596 if included != nil && (* included )[includedKey ] != nil {
619- return (* included )[includedKey ]. node
597+ return (* included )[includedKey ]
620598 }
621599
622600 return n
0 commit comments