Skip to content

Commit 516f29e

Browse files
authored
feat(sidekick): enum serialization for non-proto sources (#2410)
Change the serialization of enums for non-proto sources (discovery docs and OpenAPI) to use strings. The main motivation to use integers in the case of Protobuf is roundstrips where we receive an unknown enum from a Protobuf / gRPC response, copy that to a request, and want to serialize it without loss. That scenario is not a consideration for OpenAPI or Discovery docs, and serializing enums as integers just does not work.
1 parent c86c2db commit 516f29e

File tree

4 files changed

+27
-15
lines changed

4 files changed

+27
-15
lines changed

internal/sidekick/internal/rust/annotate.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,11 @@ type enumAnnotation struct {
448448
}
449449

450450
type enumValueAnnotation struct {
451-
Name string
452-
VariantName string
453-
EnumType string
454-
DocLines []string
451+
Name string
452+
VariantName string
453+
EnumType string
454+
DocLines []string
455+
SerializeAsString bool
455456
}
456457

457458
// annotateModel creates a struct used as input for Mustache templates.
@@ -1091,9 +1092,10 @@ func (c *codec) annotateEnum(e *api.Enum, model *api.API, full bool) {
10911092

10921093
func (c *codec) annotateEnumValue(ev *api.EnumValue, model *api.API, full bool) {
10931094
annotations := &enumValueAnnotation{
1094-
Name: enumValueName(ev),
1095-
EnumType: enumName(ev.Parent),
1096-
VariantName: enumValueVariantName(ev),
1095+
Name: enumValueName(ev),
1096+
EnumType: enumName(ev.Parent),
1097+
VariantName: enumValueVariantName(ev),
1098+
SerializeAsString: c.serializeEnumsAsStrings,
10971099
}
10981100
ev.Codec = annotations
10991101

internal/sidekick/internal/rust/codec.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ func newCodec(protobufSource bool, options map[string]string) (*codec, error) {
6565

6666
year, _, _ := time.Now().Date()
6767
codec := &codec{
68-
generationYear: fmt.Sprintf("%04d", year),
69-
modulePath: "crate::model",
70-
extraPackages: []*packagez{},
71-
packageMapping: map[string]*packagez{},
72-
version: "0.0.0",
73-
releaseLevel: "preview",
74-
systemParameters: sysParams,
68+
generationYear: fmt.Sprintf("%04d", year),
69+
modulePath: "crate::model",
70+
extraPackages: []*packagez{},
71+
packageMapping: map[string]*packagez{},
72+
version: "0.0.0",
73+
releaseLevel: "preview",
74+
systemParameters: sysParams,
75+
serializeEnumsAsStrings: !protobufSource,
7576
}
7677

7778
for key, definition := range options {
@@ -248,6 +249,8 @@ type codec struct {
248249
disabledRustdocWarnings []string
249250
// The default system parameters included in all requests.
250251
systemParameters []systemParameter
252+
// If true, enums are serialized as strings.
253+
serializeEnumsAsStrings bool
251254
// Overrides the template subdirectory.
252255
templateOverride string
253256
// If true, this includes gRPC-only methods, such as methods without HTTP

internal/sidekick/internal/rust/codec_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ func TestParseOptionsOpenAPI(t *testing.T) {
128128
systemParameters: []systemParameter{
129129
{Name: "$alt", Value: "json"},
130130
},
131+
serializeEnumsAsStrings: true,
131132
}
132133
sort.Slice(want.extraPackages, func(i, j int) bool {
133134
return want.extraPackages[i].name < want.extraPackages[j].name
@@ -166,7 +167,8 @@ func TestParseOptionsTemplateOverride(t *testing.T) {
166167
systemParameters: []systemParameter{
167168
{Name: "$alt", Value: "json"},
168169
},
169-
templateOverride: "templates/fancy-templates",
170+
serializeEnumsAsStrings: true,
171+
templateOverride: "templates/fancy-templates",
170172
}
171173
sort.Slice(want.extraPackages, func(i, j int) bool {
172174
return want.extraPackages[i].name < want.extraPackages[j].name

internal/sidekick/internal/rust/templates/common/enum.mustache

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@ impl serde::ser::Serialize for {{Codec.Name}} {
146146
{
147147
match self {
148148
{{#Codec.UniqueNames}}
149+
{{#Codec.SerializeAsString}}
150+
Self::{{Codec.VariantName}} => serializer.serialize_str("{{Name}}"),
151+
{{/Codec.SerializeAsString}}
152+
{{^Codec.SerializeAsString}}
149153
Self::{{Codec.VariantName}} => serializer.serialize_i32({{Number}}),
154+
{{/Codec.SerializeAsString}}
150155
{{/Codec.UniqueNames}}
151156
Self::UnknownValue(u) => u.0.serialize(serializer),
152157
}

0 commit comments

Comments
 (0)