From b9bc4bf94438100057c9c95a199e82ec6a48e12e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 16:34:52 +0000 Subject: [PATCH 1/4] fix: fix apijson.Port for embedded structs (#174) --- internal/apijson/port.go | 37 +++++++++++------ internal/apijson/port_test.go | 76 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 13 deletions(-) diff --git a/internal/apijson/port.go b/internal/apijson/port.go index 80b323b6..84fbb89c 100644 --- a/internal/apijson/port.go +++ b/internal/apijson/port.go @@ -34,22 +34,33 @@ func Port(from any, to any) error { fromJSON := fromVal.FieldByName("JSON") toJSON := toVal.FieldByName("JSON") - // First, iterate through the from fields 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. - for i := 0; i < fromType.NumField(); i++ { - field := fromType.Field(i) - ptag, ok := parseJSONStructTag(field) - if !ok { - continue - } - if ptag.name == "-" { - continue + // 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) { + // 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")) + continue + } } - values[ptag.name] = fromVal.Field(i) - if fromJSON.IsValid() { - fields[ptag.name] = fromJSON.FieldByName(field.Name) + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + ptag, ok := parseJSONStructTag(field) + if !ok || ptag.name == "-" { + continue + } + values[ptag.name] = v.Field(i) + if j.IsValid() { + fields[ptag.name] = j.FieldByName(field.Name) + } } } + getFields(fromType, fromVal, fromJSON) // 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 f9b6e3f4..a26a15b3 100644 --- a/internal/apijson/port_test.go +++ b/internal/apijson/port_test.go @@ -94,6 +94,37 @@ type CardMastercardData struct { Bar int64 `json:"bar"` } +type CommonFields struct { + Metadata Metadata `json:"metadata"` + Value string `json:"value"` +} + +type commonFieldsJSON struct { + Metadata Field + Value Field + ExtraFields map[string]Field +} + +type CardEmbedded struct { + CommonFields + Processor CardVisaProcessor `json:"processor"` + Data CardVisaData `json:"data"` + IsFoo bool `json:"is_foo"` + + JSON cardEmbeddedJSON +} + +type cardEmbeddedJSON struct { + commonFieldsJSON + Processor Field + Data Field + IsFoo Field + ExtraFields map[string]Field + raw string +} + +func (r cardEmbeddedJSON) RawJSON() string { return r.raw } + var portTests = map[string]struct { from any to any @@ -158,6 +189,51 @@ var portTests = map[string]struct { Value: false, }, }, + "embedded to card": { + CardEmbedded{ + CommonFields: CommonFields{ + Metadata: Metadata{ + CreatedAt: "Mar 29 2024", + }, + Value: "embedded_value", + }, + 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"}}`, + Processor: Field{raw: `"visa"`, status: valid}, + IsFoo: Field{raw: `true`, status: valid}, + Data: Field{raw: `{"foo":"embedded_foo"}`, status: valid}, + }, + }, + Card{ + Processor: "visa", + IsFoo: true, + IsBar: false, + Data: CardVisaData{ + Foo: "embedded_foo", + }, + Metadata: Metadata{ + CreatedAt: "Mar 29 2024", + }, + Value: "embedded_value", + JSON: cardJSON{ + raw: "{\"processor\":\"visa\",\"is_foo\":true,\"data\":{\"foo\":\"embedded_foo\"}}", + Processor: Field{raw: `"visa"`, status: 0x3}, + IsFoo: Field{raw: "true", status: 0x3}, + Data: Field{raw: `{"foo":"embedded_foo"}`, status: 0x3}, + Metadata: Field{raw: `{"created_at":"Mar 29 2024"}`, status: 0x3}, + Value: Field{raw: `"embedded_value"`, status: 0x3}, + }, + }, + }, } func TestPort(t *testing.T) { From 8c54a3bfe8ed07346c2eade2cabfff1f6d97a7d8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:33:09 +0000 Subject: [PATCH 2/4] chore(internal): rename `streaming.go` (#176) --- packages/ssestream/{streaming.go => ssestream.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/ssestream/{streaming.go => ssestream.go} (100%) diff --git a/packages/ssestream/streaming.go b/packages/ssestream/ssestream.go similarity index 100% rename from packages/ssestream/streaming.go rename to packages/ssestream/ssestream.go From a85df33a9fe89dffb5ce00ee297d173bb40018ed 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 3/4] 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 84fbb89c..502ab778 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 a26a15b3..11540533 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}, From a3dd19faffdbafd77261d3671c8e812366088f96 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 05:02:28 +0000 Subject: [PATCH 4/4] release: 0.1.0-alpha.48 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a9e92226..21a705e3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.47" + ".": "0.1.0-alpha.48" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b57dd957..6d15f690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.1.0-alpha.48 (2025-01-21) + +Full Changelog: [v0.1.0-alpha.47...v0.1.0-alpha.48](https://github.com/openai/openai-go/compare/v0.1.0-alpha.47...v0.1.0-alpha.48) + +### Bug Fixes + +* fix apijson.Port for embedded structs ([#174](https://github.com/openai/openai-go/issues/174)) ([b9bc4bf](https://github.com/openai/openai-go/commit/b9bc4bf94438100057c9c95a199e82ec6a48e12e)) +* fix apijson.Port for embedded structs ([#177](https://github.com/openai/openai-go/issues/177)) ([a85df33](https://github.com/openai/openai-go/commit/a85df33a9fe89dffb5ce00ee297d173bb40018ed)) + + +### Chores + +* **internal:** rename `streaming.go` ([#176](https://github.com/openai/openai-go/issues/176)) ([8c54a3b](https://github.com/openai/openai-go/commit/8c54a3bfe8ed07346c2eade2cabfff1f6d97a7d8)) + ## 0.1.0-alpha.47 (2025-01-20) Full Changelog: [v0.1.0-alpha.46...v0.1.0-alpha.47](https://github.com/openai/openai-go/compare/v0.1.0-alpha.46...v0.1.0-alpha.47) diff --git a/README.md b/README.md index 91f07a69..523828c5 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Or to pin the version: ```sh -go get -u 'github.com/openai/openai-go@v0.1.0-alpha.47' +go get -u 'github.com/openai/openai-go@v0.1.0-alpha.48' ``` diff --git a/internal/version.go b/internal/version.go index c9779c43..59b35a5e 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.1.0-alpha.47" // x-release-please-version +const PackageVersion = "0.1.0-alpha.48" // x-release-please-version