@@ -60,11 +60,6 @@ func newErrUnsupportedPtrType(rf reflect.Value, t reflect.Type, structField refl
60
60
return ErrUnsupportedPtrType {rf , t , structField }
61
61
}
62
62
63
- type includedNode struct {
64
- node * Node
65
- model * reflect.Value
66
- }
67
-
68
63
// UnmarshalPayload converts an io into a struct instance using jsonapi tags on
69
64
// struct fields. This method supports single request payloads only, at the
70
65
// moment. Bulk creates and updates are not supported yet.
@@ -99,19 +94,19 @@ type includedNode struct {
99
94
// model interface{} should be a pointer to a struct.
100
95
func UnmarshalPayload (in io.Reader , model interface {}) error {
101
96
payload := new (OnePayload )
102
- included := make (map [string ]* includedNode )
103
97
104
98
if err := json .NewDecoder (in ).Decode (payload ); err != nil {
105
99
return err
106
100
}
107
101
108
102
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
112
107
}
113
108
114
- return unmarshalNode (payload .Data , reflect .ValueOf (model ), & included )
109
+ return unmarshalNode (payload .Data , reflect .ValueOf (model ), & includedMap )
115
110
}
116
111
return unmarshalNode (payload .Data , reflect .ValueOf (model ), nil )
117
112
}
@@ -125,19 +120,19 @@ func UnmarshalManyPayload(in io.Reader, t reflect.Type) ([]interface{}, error) {
125
120
return nil , err
126
121
}
127
122
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"
130
125
131
126
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
135
130
}
136
131
}
137
132
138
133
for _ , data := range payload .Data {
139
134
model := reflect .New (t .Elem ())
140
- err := unmarshalNode (data , model , & included )
135
+ err := unmarshalNode (data , model , & includedMap )
141
136
if err != nil {
142
137
return nil , err
143
138
}
@@ -268,7 +263,7 @@ func getStructTags(field reflect.StructField) ([]string, error) {
268
263
269
264
// unmarshalNodeMaybeChoice populates a model that may or may not be
270
265
// 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 {
272
267
// This will hold either the value of the choice type model or the actual
273
268
// model, depending on annotation
274
269
var actualModel = * m
@@ -305,7 +300,7 @@ func unmarshalNodeMaybeChoice(m *reflect.Value, data *Node, annotation string, c
305
300
return nil
306
301
}
307
302
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 ) {
309
304
defer func () {
310
305
if r := recover (); r != nil {
311
306
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
534
529
continue
535
530
}
536
531
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
- }
554
532
err = unmarshalNodeMaybeChoice (& m , relationship .Data , annotation , choiceMapping , included )
555
533
if err != nil {
556
534
er = err
@@ -612,11 +590,11 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*includ
612
590
return er
613
591
}
614
592
615
- func fullNode (n * Node , included * map [string ]* includedNode ) * Node {
593
+ func fullNode (n * Node , included * map [string ]* Node ) * Node {
616
594
includedKey := fmt .Sprintf ("%s,%s" , n .Type , n .ID )
617
595
618
596
if included != nil && (* included )[includedKey ] != nil {
619
- return (* included )[includedKey ]. node
597
+ return (* included )[includedKey ]
620
598
}
621
599
622
600
return n
0 commit comments