From 1820b2592eee7aa55212c3b0bcfc3077c5d7f3a7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 22:41:15 +0000 Subject: [PATCH] fix: fix apijson.Port for embedded structs (#177) --- internal/apijson/port.go | 10 ++++++---- internal/apijson/port_test.go | 17 ++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/internal/apijson/port.go b/internal/apijson/port.go index 84fbb89..502ab77 100644 --- a/internal/apijson/port.go +++ b/internal/apijson/port.go @@ -36,14 +36,16 @@ func Port(from any, to any) error { // Iterate through the fields of v and load all the "normal" fields in the struct to the map of // string to reflect.Value, as well as their raw .JSON.Foo counterpart indicated by j. - var getFields func(t reflect.Type, v, j reflect.Value) - getFields = func(t reflect.Type, v, j reflect.Value) { + var getFields func(t reflect.Type, v reflect.Value) + getFields = func(t reflect.Type, v reflect.Value) { + j := v.FieldByName("JSON") + // Recurse into anonymous fields first, since the fields on the object should win over the fields in the // embedded object. for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Anonymous { - getFields(field.Type, v.Field(i), v.FieldByName("JSON")) + getFields(field.Type, v.Field(i)) continue } } @@ -60,7 +62,7 @@ func Port(from any, to any) error { } } } - getFields(fromType, fromVal, fromJSON) + getFields(fromType, fromVal) // Use the values from the previous step to populate the 'to' struct. for i := 0; i < toType.NumField(); i++ { diff --git a/internal/apijson/port_test.go b/internal/apijson/port_test.go index a26a15b..1154053 100644 --- a/internal/apijson/port_test.go +++ b/internal/apijson/port_test.go @@ -97,12 +97,15 @@ type CardMastercardData struct { type CommonFields struct { Metadata Metadata `json:"metadata"` Value string `json:"value"` + + JSON commonFieldsJSON } type commonFieldsJSON struct { Metadata Field Value Field ExtraFields map[string]Field + raw string } type CardEmbedded struct { @@ -115,7 +118,6 @@ type CardEmbedded struct { } type cardEmbeddedJSON struct { - commonFieldsJSON Processor Field Data Field IsFoo Field @@ -196,6 +198,11 @@ var portTests = map[string]struct { CreatedAt: "Mar 29 2024", }, Value: "embedded_value", + JSON: commonFieldsJSON{ + Metadata: Field{raw: `{"created_at":"Mar 29 2024"}`, status: valid}, + Value: Field{raw: `"embedded_value"`, status: valid}, + raw: `should not matter`, + }, }, Processor: "visa", IsFoo: true, @@ -203,11 +210,7 @@ var portTests = map[string]struct { Foo: "embedded_foo", }, JSON: cardEmbeddedJSON{ - commonFieldsJSON: commonFieldsJSON{ - Metadata: Field{raw: `{"created_at":"Mar 29 2024"}`, status: valid}, - Value: Field{raw: `"embedded_value"`, status: valid}, - }, - raw: `{"processor":"visa","is_foo":true,"data":{"foo":"embedded_foo"}}`, + raw: `{"processor":"visa","is_foo":true,"data":{"foo":"embedded_foo"},"metadata":{"created_at":"Mar 29 2024"},"value":"embedded_value"}`, Processor: Field{raw: `"visa"`, status: valid}, IsFoo: Field{raw: `true`, status: valid}, Data: Field{raw: `{"foo":"embedded_foo"}`, status: valid}, @@ -225,7 +228,7 @@ var portTests = map[string]struct { }, Value: "embedded_value", JSON: cardJSON{ - raw: "{\"processor\":\"visa\",\"is_foo\":true,\"data\":{\"foo\":\"embedded_foo\"}}", + raw: `{"processor":"visa","is_foo":true,"data":{"foo":"embedded_foo"},"metadata":{"created_at":"Mar 29 2024"},"value":"embedded_value"}`, Processor: Field{raw: `"visa"`, status: 0x3}, IsFoo: Field{raw: "true", status: 0x3}, Data: Field{raw: `{"foo":"embedded_foo"}`, status: 0x3},