Skip to content

Commit a7ce165

Browse files
Fix pointers to alias types
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
1 parent d0428f6 commit a7ce165

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

models_test.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"time"
66
)
77

8+
type StringType string
9+
810
type BadModel struct {
911
ID int `jsonapi:"primary"`
1012
}
@@ -18,11 +20,12 @@ type ModelBadTypes struct {
1820
}
1921

2022
type WithPointer struct {
21-
ID *uint64 `jsonapi:"primary,with-pointers"`
22-
Name *string `jsonapi:"attr,name"`
23-
IsActive *bool `jsonapi:"attr,is-active"`
24-
IntVal *int `jsonapi:"attr,int-val"`
25-
FloatVal *float32 `jsonapi:"attr,float-val"`
23+
ID *uint64 `jsonapi:"primary,with-pointers"`
24+
Name *string `jsonapi:"attr,name"`
25+
IsActive *bool `jsonapi:"attr,is-active"`
26+
IntVal *int `jsonapi:"attr,int-val"`
27+
FloatVal *float32 `jsonapi:"attr,float-val"`
28+
String *StringType `jsonapi:"attr,string"`
2629
}
2730

2831
type Timestamp struct {

request.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ func handlePointer(
580580
reflect.ValueOf(attribute), fieldType, structField)
581581
}
582582

583-
if t != concreteVal.Type() {
583+
if !t.ConvertibleTo(concreteVal.Type()) {
584584
return reflect.Value{}, newErrUnsupportedPtrType(
585585
reflect.ValueOf(attribute), fieldType, structField)
586586
}

request_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,32 @@ func TestUnmarshall_attrStringSlice(t *testing.T) {
4545
}
4646
}
4747

48+
func TestUnmarshalToStructWithPointerToNamedType(t *testing.T) {
49+
out := new(WithPointer)
50+
in := map[string]interface{}{
51+
"string": "foo",
52+
}
53+
if err := UnmarshalPayload(sampleWithPointerPayload(in), out); err != nil {
54+
t.Fatal(err)
55+
}
56+
if *out.String != "foo" {
57+
t.Fatalf("Error unmarshalling to string alias ptr")
58+
}
59+
}
60+
61+
func TestUnmarshalToStructWithPointerToNamedTypeNull(t *testing.T) {
62+
out := new(WithPointer)
63+
in := map[string]interface{}{
64+
"string": nil,
65+
}
66+
if err := UnmarshalPayload(sampleWithPointerPayload(in), out); err != nil {
67+
t.Fatal(err)
68+
}
69+
if out.String != nil {
70+
t.Fatalf("Error unmarshalling to string alias ptr")
71+
}
72+
}
73+
4874
func TestUnmarshalToStructWithPointerAttr(t *testing.T) {
4975
out := new(WithPointer)
5076
in := map[string]interface{}{
@@ -68,6 +94,9 @@ func TestUnmarshalToStructWithPointerAttr(t *testing.T) {
6894
if *out.FloatVal != 1.1 {
6995
t.Fatalf("Error unmarshalling to float ptr")
7096
}
97+
if out.String != nil {
98+
t.Fatalf("Error unmarshalling to string alias ptr")
99+
}
71100
}
72101

73102
func TestUnmarshalPayload_ptrsAllNil(t *testing.T) {

0 commit comments

Comments
 (0)