@@ -274,6 +274,7 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
274
274
json .NewDecoder (buf ).Decode (relationship )
275
275
276
276
data := relationship .Data
277
+ links := relationship .Links
277
278
models := reflect .New (fieldValue .Type ()).Elem ()
278
279
279
280
for _ , n := range data {
@@ -291,6 +292,37 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
291
292
models = reflect .Append (models , m )
292
293
}
293
294
295
+ if links != nil {
296
+ var assignedValue bool
297
+ linkModel := reflect .New (fieldValue .Type ().Elem ().Elem ())
298
+ linkModelValue := linkModel .Elem ()
299
+ linkModelType := linkModelValue .Type ()
300
+
301
+ for i := 0 ; i < linkModelValue .NumField (); i ++ {
302
+ fieldType := linkModelType .Field (i )
303
+ tag := fieldType .Tag .Get ("jsonapi" )
304
+ if tag == "" {
305
+ continue
306
+ }
307
+ fieldValue := linkModelValue .Field (i )
308
+ args := strings .Split (tag , "," )
309
+ annotation := args [0 ]
310
+ if annotation == annotationLinks {
311
+ value , err := unmarshalAttribute (* links , args , fieldType , fieldValue )
312
+ if err != nil {
313
+ er = err
314
+ break
315
+ }
316
+
317
+ assign (fieldValue , value )
318
+ assignedValue = true
319
+ }
320
+ }
321
+ if assignedValue {
322
+ models = reflect .Append (models , linkModel )
323
+ }
324
+ }
325
+
294
326
fieldValue .Set (models )
295
327
} else {
296
328
// to-one relationships
@@ -309,13 +341,23 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
309
341
relationship can have a data node set to null (e.g. to disassociate the relationship)
310
342
so unmarshal and set fieldValue only if data obj is not null
311
343
*/
312
- if relationship .Data == nil {
344
+
345
+ if relationship .Data == nil && relationship .Links == nil {
313
346
continue
314
347
}
315
348
349
+ node := & Node {}
350
+ if relationship .Data != nil {
351
+ node = relationship .Data
352
+ }
353
+
354
+ if relationship .Links != nil {
355
+ node .Links = relationship .Links
356
+ }
357
+
316
358
m := reflect .New (fieldValue .Type ().Elem ())
317
359
if err := unmarshalNode (
318
- fullNode (relationship . Data , included ),
360
+ fullNode (node , included ),
319
361
m ,
320
362
included ,
321
363
); err != nil {
@@ -324,9 +366,23 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
324
366
}
325
367
326
368
fieldValue .Set (m )
369
+ }
370
+
371
+ } else if annotation == annotationLinks {
372
+ links := data .Links
373
+ if links == nil {
374
+ continue
375
+ }
327
376
377
+ structField := fieldType
378
+ value , err := unmarshalAttribute (* links , args , structField , fieldValue )
379
+ if err != nil {
380
+ er = err
381
+ break
328
382
}
329
383
384
+ assign (fieldValue , value )
385
+
330
386
} else {
331
387
er = fmt .Errorf (unsupportedStructTagMsg , annotation )
332
388
}
@@ -409,6 +465,11 @@ func unmarshalAttribute(
409
465
return
410
466
}
411
467
468
+ if fieldValue .Type () == reflect .TypeOf (& Links {}) {
469
+ value , err = handleLinks (attribute , args , fieldValue )
470
+ return
471
+ }
472
+
412
473
// Handle field of type struct
413
474
if fieldValue .Type ().Kind () == reflect .Struct {
414
475
value , err = handleStruct (attribute , fieldValue )
@@ -466,6 +527,25 @@ func handleMapStringSlice(attribute interface{}, fieldValue reflect.Value) (refl
466
527
return reflect .ValueOf (values ), nil
467
528
}
468
529
530
+ func handleLinks (attribute interface {}, args []string , fieldValue reflect.Value ) (reflect.Value , error ) {
531
+ b , err := json .Marshal (attribute )
532
+ if err != nil {
533
+ return reflect.Value {}, err
534
+ }
535
+ var v interface {}
536
+ err = json .Unmarshal (b , & v )
537
+ if err != nil {
538
+ return reflect.Value {}, err
539
+ }
540
+
541
+ var values = map [string ]interface {}{}
542
+ for k , v := range v .(map [string ]interface {}) {
543
+ values [k ] = v .(interface {})
544
+ }
545
+
546
+ return reflect .ValueOf (values ), nil
547
+ }
548
+
469
549
func handleTime (attribute interface {}, args []string , fieldValue reflect.Value ) (reflect.Value , error ) {
470
550
var isIso8601 bool
471
551
var isRFC3339 bool
0 commit comments