Skip to content

Commit c10a88b

Browse files
committed
Support camel case
1 parent bc86f94 commit c10a88b

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

pbjson-build/src/generator/enumeration.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use super::{
1111
use crate::descriptor::{EnumDescriptor, TypePath};
1212
use crate::generator::write_fields_array;
1313
use crate::resolver::Resolver;
14+
use heck::ToUpperCamelCase;
1415
use std::collections::HashSet;
16+
use itertools::Itertools;
1517
use std::io::{Result, Write};
1618

1719
pub fn generate_enum<W: Write>(
@@ -20,6 +22,7 @@ pub fn generate_enum<W: Write>(
2022
descriptor: &EnumDescriptor,
2123
writer: &mut W,
2224
use_integers_for_enums: bool,
25+
support_camel_case_for_enum_deserialization: bool,
2326
) -> Result<()> {
2427
let rust_type = resolver.rust_type(path);
2528

@@ -74,7 +77,13 @@ pub fn generate_enum<W: Write>(
7477
// Generate Deserialize
7578
write_deserialize_start(0, &rust_type, writer)?;
7679
write_fields_array(writer, 2, variants.iter().map(|(name, _, _)| name.as_str()))?;
77-
write_visitor(writer, 2, &rust_type, &variants)?;
80+
write_visitor(
81+
writer,
82+
2,
83+
&rust_type,
84+
&variants,
85+
support_camel_case_for_enum_deserialization,
86+
)?;
7887

7988
// Use deserialize_any to allow users to provide integers or strings
8089
writeln!(
@@ -92,6 +101,7 @@ fn write_visitor<W: Write>(
92101
indent: usize,
93102
rust_type: &str,
94103
variants: &[(String, i32, String)],
104+
support_camel_case_for_enum_deserialization: bool,
95105
) -> Result<()> {
96106
// Protobuf supports deserialization of enumerations both from string and integer values
97107
writeln!(
@@ -139,14 +149,22 @@ fn write_visitor<W: Write>(
139149

140150
writeln!(writer, "{}match value {{", Indent(indent + 2))?;
141151
for (variant_name, _, rust_variant) in variants {
152+
let mut variants = vec![variant_name.to_string()];
153+
if support_camel_case_for_enum_deserialization {
154+
let camel_case = variant_name.to_upper_camel_case();
155+
variants.push(camel_case);
156+
variants.dedup();
157+
}
158+
let variants = variants.into_iter().map(|variant| format!("\"{variant}\"")).join(" | ");
142159
writeln!(
143160
writer,
144161
"{}\"{}\" => Ok({}::{}),",
145162
Indent(indent + 3),
146-
variant_name,
163+
variants,
147164
rust_type,
148165
rust_variant
149166
)?;
167+
150168
}
151169

152170
writeln!(

pbjson-build/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub struct Builder {
107107
btree_map_paths: Vec<String>,
108108
emit_fields: bool,
109109
use_integers_for_enums: bool,
110+
support_camel_case_for_enum_deserialization: bool,
110111
preserve_proto_field_names: bool,
111112
}
112113

@@ -186,12 +187,19 @@ impl Builder {
186187
self.emit_fields = true;
187188
self
188189
}
190+
189191
// print integers instead of enum names.
190192
pub fn use_integers_for_enums(&mut self) -> &mut Self {
191193
self.use_integers_for_enums = true;
192194
self
193195
}
194196

197+
// Deserialize camelCased strings as enums.
198+
pub fn support_camel_case_for_enum_deserialization(&mut self) -> &mut Self {
199+
self.support_camel_case_for_enum_deserialization = true;
200+
self
201+
}
202+
195203
/// Output fields with their original names as defined in their proto schemas, instead of
196204
/// lowerCamelCase
197205
pub fn preserve_proto_field_names(&mut self) -> &mut Self {
@@ -277,6 +285,7 @@ impl Builder {
277285
descriptor,
278286
writer,
279287
self.use_integers_for_enums,
288+
self.support_camel_case_for_enum_deserialization,
280289
)?,
281290
Descriptor::Message(descriptor) => {
282291
if let Some(message) = resolve_message(&self.descriptors, descriptor) {

0 commit comments

Comments
 (0)