Skip to content

Commit 7b0afb9

Browse files
committed
Add struct handling
1 parent 824c4ed commit 7b0afb9

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

request.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,27 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
247247
}
248248

249249
structField := fieldType
250-
value, err := unmarshalAttribute(attribute, args, structField, fieldValue)
251-
if err != nil {
252-
er = err
253-
break
254-
}
255250

256-
assign(fieldValue, value)
257-
continue
251+
if structField.Type.Kind() != reflect.Struct ||
252+
fieldValue.Type() == reflect.TypeOf(new(time.Time)) ||
253+
fieldValue.Type() == reflect.TypeOf(time.Time{}) {
254+
value, err := unmarshalAttribute(attribute, args, structField, fieldValue)
255+
if err != nil {
256+
er = err
257+
break
258+
}
259+
assign(fieldValue, value)
260+
continue
258261

262+
} else {
263+
structModel, err := unmarshalFromAttribute(attribute, fieldValue)
264+
if err != nil {
265+
er = err
266+
break
267+
}
268+
fieldValue.Set((*structModel).Elem())
269+
continue
270+
}
259271
} else if annotation == annotationRelation {
260272
isSlice := fieldValue.Type().Kind() == reflect.Slice
261273

@@ -334,6 +346,23 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
334346
return er
335347
}
336348

349+
func unmarshalFromAttribute(attribute interface{}, fieldValue reflect.Value) (*reflect.Value, error) {
350+
structData, err := json.Marshal(attribute)
351+
if err != nil {
352+
return nil, err
353+
}
354+
structNode := new(Node)
355+
if err := json.Unmarshal(structData, &structNode.Attributes); err != nil {
356+
return nil, err
357+
}
358+
structModel := reflect.New(fieldValue.Type())
359+
if err := unmarshalNode(structNode, structModel, nil); err != nil {
360+
return nil, err
361+
}
362+
363+
return &structModel, nil
364+
}
365+
337366
func fullNode(n *Node, included *map[string]*Node) *Node {
338367
includedKey := fmt.Sprintf("%s,%s", n.Type, n.ID)
339368

@@ -347,7 +376,7 @@ func fullNode(n *Node, included *map[string]*Node) *Node {
347376
// assign will take the value specified and assign it to the field; if
348377
// field is expecting a ptr assign will assign a ptr.
349378
func assign(field, value reflect.Value) {
350-
if field.Kind() == reflect.Ptr {
379+
if field.Kind() == reflect.Ptr || field.Kind() == reflect.Struct{
351380
field.Set(value)
352381
} else {
353382
field.Set(reflect.Indirect(value))
@@ -362,6 +391,7 @@ func unmarshalAttribute(
362391
value = reflect.ValueOf(attribute)
363392
fieldType := structField.Type
364393

394+
365395
// Handle field of type []string
366396
if fieldValue.Type() == reflect.TypeOf([]string{}) {
367397
value, err = handleStringSlice(attribute)
@@ -566,7 +596,6 @@ func handlePointer(
566596
func handleStruct(
567597
attribute interface{},
568598
fieldValue reflect.Value) (reflect.Value, error) {
569-
570599
data, err := json.Marshal(attribute)
571600
if err != nil {
572601
return reflect.Value{}, err

response.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,13 @@ func visitModelNode(model interface{}, included *map[string]*Node,
207207
node := new(Node)
208208

209209
var er error
210-
value := reflect.ValueOf(model)
210+
var value reflect.Value
211+
if modelValue, ok := model.(reflect.Value); ok {
212+
value = modelValue.Addr()
213+
} else {
214+
value = reflect.ValueOf(model)
215+
}
216+
211217
if value.IsNil() {
212218
return nil, nil
213219
}
@@ -340,6 +346,28 @@ func visitModelNode(model interface{}, included *map[string]*Node,
340346
node.Attributes[args[1]] = tm.Unix()
341347
}
342348
}
349+
} else if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() == reflect.Struct {
350+
newSlice := make([]map[string]interface{}, fieldValue.Len())
351+
for i:=0; i < fieldValue.Len(); i++ {
352+
included := make(map[string]*Node)
353+
nested, err := visitModelNode(fieldValue.Index(i), &included, true)
354+
if err != nil {
355+
er = err
356+
break
357+
}
358+
359+
newSlice[i] = nested.Attributes
360+
}
361+
node.Attributes[args[1]] = newSlice
362+
} else if fieldValue.Kind() == reflect.Struct {
363+
included := make(map[string]*Node)
364+
nested, err := visitModelNode(fieldValue, &included, true)
365+
if err != nil {
366+
er = err
367+
break
368+
}
369+
370+
node.Attributes[args[1]] = nested.Attributes
343371
} else {
344372
// Dealing with a fieldValue that is not a time
345373
emptyValue := reflect.Zero(fieldValue.Type())

0 commit comments

Comments
 (0)