Skip to content

Commit

Permalink
Fix pointers to alias types
Browse files Browse the repository at this point in the history
This commit fixes pointers to type aliases which are currently not
supported.

The new test cases will fail with:
  jsonapi: Can't unmarshal foo (string) to struct field `String`, which is a pointer to `StringType (string)`

One other method to fix this when you are able to modify your types is:

  type StringType = string

This is the new (since Go 1.9) way to declare type aliasses which treats
the types differently when using reflect.
See: https://github.com/golang/example/tree/master/gotypes#named-types
  • Loading branch information
erikdubbelboer committed Feb 4, 2020
1 parent d0428f6 commit ec5ed79
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
13 changes: 8 additions & 5 deletions models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"time"
)

type StringType string

type BadModel struct {
ID int `jsonapi:"primary"`
}
Expand All @@ -18,11 +20,12 @@ type ModelBadTypes struct {
}

type WithPointer struct {
ID *uint64 `jsonapi:"primary,with-pointers"`
Name *string `jsonapi:"attr,name"`
IsActive *bool `jsonapi:"attr,is-active"`
IntVal *int `jsonapi:"attr,int-val"`
FloatVal *float32 `jsonapi:"attr,float-val"`
ID *uint64 `jsonapi:"primary,with-pointers"`
Name *string `jsonapi:"attr,name"`
IsActive *bool `jsonapi:"attr,is-active"`
IntVal *int `jsonapi:"attr,int-val"`
FloatVal *float32 `jsonapi:"attr,float-val"`
StringVal *StringType `jsonapi:"attr,string-val"`
}

type Timestamp struct {
Expand Down
2 changes: 1 addition & 1 deletion request.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ func handlePointer(
reflect.ValueOf(attribute), fieldType, structField)
}

if t != concreteVal.Type() {
if !t.ConvertibleTo(concreteVal.Type()) {
return reflect.Value{}, newErrUnsupportedPtrType(
reflect.ValueOf(attribute), fieldType, structField)
}
Expand Down
29 changes: 29 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,32 @@ func TestUnmarshall_attrStringSlice(t *testing.T) {
}
}

func TestUnmarshalToStructWithPointerToNamedType(t *testing.T) {
out := new(WithPointer)
in := map[string]interface{}{
"string-val": "foo",
}
if err := UnmarshalPayload(sampleWithPointerPayload(in), out); err != nil {
t.Fatal(err)
}
if *out.StringVal != "foo" {
t.Fatalf("Error unmarshalling to string alias ptr")
}
}

func TestUnmarshalToStructWithPointerToNamedTypeNull(t *testing.T) {
out := new(WithPointer)
in := map[string]interface{}{
"string-val": nil,
}
if err := UnmarshalPayload(sampleWithPointerPayload(in), out); err != nil {
t.Fatal(err)
}
if out.StringVal != nil {
t.Fatalf("Error unmarshalling to string alias ptr")
}
}

func TestUnmarshalToStructWithPointerAttr(t *testing.T) {
out := new(WithPointer)
in := map[string]interface{}{
Expand All @@ -68,6 +94,9 @@ func TestUnmarshalToStructWithPointerAttr(t *testing.T) {
if *out.FloatVal != 1.1 {
t.Fatalf("Error unmarshalling to float ptr")
}
if out.StringVal != nil {
t.Fatalf("Error unmarshalling to string alias ptr")
}
}

func TestUnmarshalPayload_ptrsAllNil(t *testing.T) {
Expand Down

0 comments on commit ec5ed79

Please sign in to comment.