Skip to content

Commit dc81607

Browse files
Merge pull request #1 from michele/master
Add custom types
2 parents d0428f6 + fa5f730 commit dc81607

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

request.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,11 @@ func unmarshalAttribute(
393393
return
394394
}
395395

396+
// Handle field of type json.RawMessage
397+
if fieldValue.Type() == reflect.TypeOf(json.RawMessage{}) {
398+
value, err = handleJSONRawMessage(attribute)
399+
}
400+
396401
// Handle field of type time.Time
397402
if fieldValue.Type() == reflect.TypeOf(time.Time{}) ||
398403
fieldValue.Type() == reflect.TypeOf(new(time.Time)) {
@@ -444,6 +449,14 @@ func handleStringSlice(attribute interface{}) (reflect.Value, error) {
444449
return reflect.ValueOf(values), nil
445450
}
446451

452+
func handleJSONRawMessage(attribute interface{}) (reflect.Value, error) {
453+
tmp, err := json.Marshal(attribute)
454+
if err != nil {
455+
return reflect.Value{}, err
456+
}
457+
return reflect.ValueOf(json.RawMessage(tmp)), nil
458+
}
459+
447460
func handleTime(attribute interface{}, args []string, fieldValue reflect.Value) (reflect.Value, error) {
448461
var isIso8601 bool
449462
v := reflect.ValueOf(attribute)
@@ -591,7 +604,19 @@ func handlePointer(
591604
func handleStruct(
592605
attribute interface{},
593606
fieldValue reflect.Value) (reflect.Value, error) {
594-
607+
if fieldValue.CanAddr() {
608+
interf := fieldValue.Addr().Interface()
609+
if _, ok := interf.(json.Unmarshaler); ok {
610+
var tmp []byte
611+
tmp, err := json.Marshal(attribute)
612+
if err == nil {
613+
err = json.Unmarshal(tmp, interf)
614+
if err == nil {
615+
return reflect.ValueOf(interf), nil
616+
}
617+
}
618+
}
619+
}
595620
data, err := json.Marshal(attribute)
596621
if err != nil {
597622
return reflect.Value{}, err

request_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,3 +1306,75 @@ func TestUnmarshalNestedStructSlice(t *testing.T) {
13061306
out.Teams[0].Members[0].Firstname)
13071307
}
13081308
}
1309+
1310+
type MyCustomAttribute struct {
1311+
Field string
1312+
}
1313+
1314+
func (mca MyCustomAttribute) MarshalJSON() ([]byte, error) {
1315+
return json.Marshal(mca.Field)
1316+
}
1317+
func (mca *MyCustomAttribute) UnmarshalJSON(bts []byte) error {
1318+
return json.Unmarshal(bts, &mca.Field)
1319+
}
1320+
1321+
type StructForTest struct {
1322+
ID string `jsonapi:"primary,tests"`
1323+
Custom MyCustomAttribute `jsonapi:"attr,custom,omitempty"`
1324+
Raw json.RawMessage `jsonapi:"attr,raw,omitempty"`
1325+
}
1326+
1327+
func TestUnmarshalWithCustomType(t *testing.T) {
1328+
sft := &StructForTest{
1329+
ID: "my-id",
1330+
Custom: MyCustomAttribute{
1331+
Field: "a-string",
1332+
},
1333+
}
1334+
buf := new(bytes.Buffer)
1335+
err := MarshalPayload(buf, sft)
1336+
if err != nil {
1337+
t.Fatal(err)
1338+
}
1339+
newSft := &StructForTest{}
1340+
err = UnmarshalPayload(buf, newSft)
1341+
1342+
if err != nil {
1343+
t.Fatal(err)
1344+
}
1345+
1346+
if sft.Custom.Field != newSft.Custom.Field {
1347+
t.Fatalf("Custom type wasn't properly unmarshalled: Expected to have `%s` but got `%s`",
1348+
sft.Custom.Field, newSft.Custom.Field)
1349+
}
1350+
}
1351+
1352+
func TestUnmarshalWithJSONRawMessage(t *testing.T) {
1353+
tests := [][]byte{
1354+
[]byte(`{"really":{"deep":true},"test":"toast"}`),
1355+
[]byte(`"just a string"`),
1356+
[]byte(`123`),
1357+
}
1358+
for _, v := range tests {
1359+
sft := &StructForTest{
1360+
ID: "my-id",
1361+
Raw: v,
1362+
}
1363+
buf := new(bytes.Buffer)
1364+
err := MarshalPayload(buf, sft)
1365+
if err != nil {
1366+
t.Fatal(err)
1367+
}
1368+
newSft := &StructForTest{}
1369+
err = UnmarshalPayload(buf, newSft)
1370+
1371+
if err != nil {
1372+
t.Fatal(err)
1373+
}
1374+
1375+
if bytes.Compare(sft.Raw, newSft.Raw) != 0 {
1376+
t.Fatalf("json.RawMessage wasn't properly unmarshalled: Expected to have `%s` but got `%s`",
1377+
string(sft.Raw), string(newSft.Raw))
1378+
}
1379+
}
1380+
}

0 commit comments

Comments
 (0)