Skip to content

Commit

Permalink
fix: fix apijson.Port for embedded structs (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-app[bot] committed Jan 21, 2025
1 parent fb192c6 commit 1820b25
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
10 changes: 6 additions & 4 deletions internal/apijson/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand All @@ -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++ {
Expand Down
17 changes: 10 additions & 7 deletions internal/apijson/port_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -115,7 +118,6 @@ type CardEmbedded struct {
}

type cardEmbeddedJSON struct {
commonFieldsJSON
Processor Field
Data Field
IsFoo Field
Expand Down Expand Up @@ -196,18 +198,19 @@ 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,
Data: CardVisaData{
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},
Expand All @@ -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},
Expand Down

0 comments on commit 1820b25

Please sign in to comment.