Merge branch 'master' of github.com:shwoodard/jsonapi

* 'master' of github.com:shwoodard/jsonapi:
  make utility function to output embedded records
  explicitly check for float64
  Add test for set id
This commit is contained in:
Sam Woodard 2015-07-08 16:48:19 -07:00
commit 6f271d2ac7
3 changed files with 74 additions and 30 deletions

View File

@ -106,7 +106,7 @@ func unmarshalJsonApiNode(data *JsonApiNode, model reflect.Value) error {
return false return false
} }
if fieldValue.Kind() == reflect.Int && v.Kind() != reflect.Int { if fieldValue.Kind() == reflect.Int && v.Kind() == reflect.Float64 {
fieldValue.Set(reflect.ValueOf(int(v.Interface().(float64)))) fieldValue.Set(reflect.ValueOf(int(v.Interface().(float64))))
} else { } else {
fieldValue.Set(reflect.ValueOf(val)) fieldValue.Set(reflect.ValueOf(val))

View File

@ -26,18 +26,18 @@ func TestMalformedTag(t *testing.T) {
} }
} }
//func TestUnmarshalSetsId(t *testing.T) { func TestUnmarshalSetsId(t *testing.T) {
//in := samplePayload() in := samplePayloadWithId()
//out := new(Blog) out := new(Blog)
//if err := UnmarshalJsonApiPayload(in, out); err != nil { if err := UnmarshalJsonApiPayload(in, out); err != nil {
//t.Fatal(err) t.Fatal(err)
//} }
//if out.Id != 0 { if out.Id != 2 {
//t.Fatalf("Did not set Id on dst interface") t.Fatalf("Did not set Id on dst interface")
//} }
//} }
func TestUnmarshalSetsAttrs(t *testing.T) { func TestUnmarshalSetsAttrs(t *testing.T) {
out, err := unmarshalSamplePayload() out, err := unmarshalSamplePayload()
@ -173,3 +173,23 @@ func samplePayload() io.Reader {
return out return out
} }
func samplePayloadWithId() io.Reader {
payload := &JsonApiOnePayload{
Data: &JsonApiNode{
Id: "2",
Type: "blogs",
Attributes: map[string]interface{}{
"title": "New blog",
"created_at": 1436216820,
"view_count": 1000,
},
},
}
out := bytes.NewBuffer(nil)
json.NewEncoder(out).Encode(payload)
return out
}

View File

@ -15,7 +15,7 @@ func MarshalJsonApiManyPayload(models Models) (*JsonApiManyPayload, error) {
incl := make([]*JsonApiNode, 0) incl := make([]*JsonApiNode, 0)
for _, model := range d { for _, model := range d {
node, included, err := visitModelNode(model) node, included, err := visitModelNode(model, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -40,8 +40,20 @@ func MarshalJsonApiManyPayload(models Models) (*JsonApiManyPayload, error) {
}, nil }, nil
} }
func MarshalJsonApiOnePayloadEmbedded(model interface{}) (*JsonApiOnePayload, error) {
rootNode, _, err := visitModelNode(model, false)
if err != nil {
return nil, err
}
resp := &JsonApiOnePayload{Data: rootNode}
return resp, nil
}
func MarshalJsonApiOnePayload(model interface{}) (*JsonApiOnePayload, error) { func MarshalJsonApiOnePayload(model interface{}) (*JsonApiOnePayload, error) {
rootNode, included, err := visitModelNode(model) rootNode, included, err := visitModelNode(model, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -64,7 +76,7 @@ func MarshalJsonApiOnePayload(model interface{}) (*JsonApiOnePayload, error) {
return resp, nil return resp, nil
} }
func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) { func visitModelNode(model interface{}, sideload bool) (*JsonApiNode, []*JsonApiNode, error) {
node := new(JsonApiNode) node := new(JsonApiNode)
var er error var er error
@ -82,6 +94,10 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
tag := structField.Tag.Get("jsonapi") tag := structField.Tag.Get("jsonapi")
if tag == "" {
return false
}
args := strings.Split(tag, ",") args := strings.Split(tag, ",")
if len(args) != 2 { if len(args) != 2 {
@ -134,10 +150,11 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
} }
if isSlice { if isSlice {
relationship, err := visitModelNodeRelationships(args[1], fieldValue) relationship, err := visitModelNodeRelationships(args[1], fieldValue, sideload)
d := relationship[args[1]].Data d := relationship[args[1]].Data
if err == nil { if err == nil {
if sideload {
shallowNodes := make([]*JsonApiNode, 0) shallowNodes := make([]*JsonApiNode, 0)
for _, node := range d { for _, node := range d {
included = append(included, node) included = append(included, node)
@ -149,19 +166,26 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
} }
node.Relationships[args[1]] = &JsonApiRelationshipManyNode{Data: shallowNodes} node.Relationships[args[1]] = &JsonApiRelationshipManyNode{Data: shallowNodes}
} else {
node.Relationships[args[1]] = &JsonApiRelationshipManyNode{Data: d}
}
} else { } else {
er = err er = err
return false return false
} }
} else { } else {
relationship, _, err := visitModelNode(fieldValue.Interface()) relationship, _, err := visitModelNode(fieldValue.Interface(), sideload)
if err == nil { if err == nil {
if sideload {
shallowNode := *relationship shallowNode := *relationship
shallowNode.Attributes = nil shallowNode.Attributes = nil
included = append(included, relationship) included = append(included, relationship)
node.Relationships[args[1]] = &JsonApiRelationshipOneNode{Data: &shallowNode} node.Relationships[args[1]] = &JsonApiRelationshipOneNode{Data: &shallowNode}
} else {
node.Relationships[args[1]] = &JsonApiRelationshipOneNode{Data: relationship}
}
} else { } else {
er = err er = err
return false return false
@ -184,12 +208,12 @@ func visitModelNode(model interface{}) (*JsonApiNode, []*JsonApiNode, error) {
return node, included, nil return node, included, nil
} }
func visitModelNodeRelationships(relationName string, models reflect.Value) (map[string]*JsonApiRelationshipManyNode, error) { func visitModelNodeRelationships(relationName string, models reflect.Value, sideload bool) (map[string]*JsonApiRelationshipManyNode, error) {
m := make(map[string]*JsonApiRelationshipManyNode) m := make(map[string]*JsonApiRelationshipManyNode)
nodes := make([]*JsonApiNode, 0) nodes := make([]*JsonApiNode, 0)
for i := 0; i < models.Len(); i++ { for i := 0; i < models.Len(); i++ {
node, _, err := visitModelNode(models.Index(i).Interface()) node, _, err := visitModelNode(models.Index(i).Interface(), sideload)
if err != nil { if err != nil {
return nil, err return nil, err
} }