diff --git a/pbjson-build/src/generator/message.rs b/pbjson-build/src/generator/message.rs index 4fd13fd..f5fc404 100644 --- a/pbjson-build/src/generator/message.rs +++ b/pbjson-build/src/generator/message.rs @@ -610,14 +610,26 @@ fn write_deserialize_field_name( ) -> Result<()> { let fields: Vec<_> = message .all_fields() - .map(|field| (field.json_name(), field.rust_type_name())) + .map(|field| { + let json_name = field.json_name(); + // only carry the original proto name if it's different from the provided json name + let proto_name = + Some(field.name.as_str()).filter(|proto_name| proto_name != &json_name); + (json_name, field.rust_type_name(), proto_name) + }) .collect(); - write_fields_array(writer, indent, fields.iter().map(|(name, _)| name.as_str()))?; + write_fields_array( + writer, + indent, + fields.iter().flat_map(|(json_name, _, proto_name)| { + proto_name.iter().copied().chain([json_name.as_str()]) + }), + )?; write_fields_enum( writer, indent, - fields.iter().map(|(_, name)| name.as_str()), + fields.iter().map(|(_, type_name, _)| type_name.as_str()), ignore_unknown_fields, )?; @@ -647,14 +659,25 @@ fn write_deserialize_field_name( if !fields.is_empty() { writeln!(writer, "{}match value {{", Indent(indent + 4))?; - for (json_name, type_name) in &fields { - writeln!( - writer, - "{}\"{}\" => Ok(GeneratedField::{}),", - Indent(indent + 5), - json_name, - type_name - )?; + for (json_name, type_name, proto_name) in &fields { + if let Some(proto_name) = proto_name { + writeln!( + writer, + "{}\"{}\" | \"{}\" => Ok(GeneratedField::{}),", + Indent(indent + 5), + json_name, + proto_name, + type_name + )?; + } else { + writeln!( + writer, + "{}\"{}\" => Ok(GeneratedField::{}),", + Indent(indent + 5), + json_name, + type_name + )?; + } } if ignore_unknown_fields { writeln!( diff --git a/pbjson-test/src/lib.rs b/pbjson-test/src/lib.rs index f4a22a8..7954e1d 100644 --- a/pbjson-test/src/lib.rs +++ b/pbjson-test/src/lib.rs @@ -149,6 +149,7 @@ mod tests { // Can also decode from string verify_decode(&decoded, r#"{"optionalI32":"0"}"#); + verify_decode(&decoded, r#"{"optional_i32":"0"}"#); decoded.optional_i32 = None; verify_decode(&decoded, "{}"); @@ -168,6 +169,7 @@ mod tests { // Can also decode from non-string verify_decode(&decoded, r#"{"optionalI64":0}"#); + verify_decode(&decoded, r#"{"optional_i64":0}"#); decoded.optional_i64 = None; verify_decode(&decoded, "{}"); @@ -191,6 +193,7 @@ mod tests { verify(&decoded, r#"{"repeatedI32":[0,23,5,6,2,34]}"#); // Can also mix in some strings verify_decode(&decoded, r#"{"repeatedI32":[0,"23",5,6,"2",34]}"#); + verify_decode(&decoded, r#"{"repeated_i32":[0,"23",5,6,"2",34]}"#); decoded.repeated_i32 = vec![]; verify_decode(&decoded, "{}"); @@ -199,6 +202,7 @@ mod tests { verify(&decoded, r#"{"repeatedU64":["0","532","2"]}"#); // Can also mix in some non-strings verify_decode(&decoded, r#"{"repeatedU64":["0",532,"2"]}"#); + verify_decode(&decoded, r#"{"repeated_u64":["0",532,"2"]}"#); decoded.repeated_u64 = vec![]; verify_decode(&decoded, "{}"); @@ -218,6 +222,7 @@ mod tests { // Can also use variant number verify_decode(&decoded, r#"{"optionalValue":0}"#); + verify_decode(&decoded, r#"{"optional_value":0}"#); decoded.optional_value = None; verify_decode(&decoded, "{}"); @@ -238,6 +243,7 @@ mod tests { verify(&decoded, r#"{"int32Dict":{"343":"A"}}"#); // Enum dictionary values can be decoded from integers verify_decode(&decoded, r#"{"int32Dict":{"343":66}}"#); + verify_decode(&decoded, r#"{"int32_dict":{"343":66}}"#); decoded.int32_dict = Default::default(); verify_decode(&decoded, "{}"); @@ -247,6 +253,7 @@ mod tests { verify(&decoded, r#"{"integerDict":{"12":"13"}}"#); // 64-bit dictionary values can be decoded from numeric types verify_decode(&decoded, r#"{"integerDict":{"12":13}}"#); + verify_decode(&decoded, r#"{"integer_dict":{"12":13}}"#); decoded.integer_dict = Default::default(); verify_decode(&decoded, "{}"); @@ -255,6 +262,7 @@ mod tests { verify(&decoded, r#"{"oneOfI32":0}"#); // Can also specify string verify_decode(&decoded, r#"{"oneOfI32":"0"}"#); + verify_decode(&decoded, r#"{"one_of_i32":"0"}"#); decoded.one_of = Some(kitchen_sink::OneOf::OneOfI32(12)); verify(&decoded, r#"{"oneOfI32":12}"#); @@ -271,6 +279,7 @@ mod tests { verify(&decoded, r#"{"oneOfValue":"VALUE_B"}"#); // Can also specify enum variant verify_decode(&decoded, r#"{"oneOfValue":63}"#); + verify_decode(&decoded, r#"{"one_of_value":63}"#); decoded.one_of = None; verify_decode(&decoded, "{}"); @@ -285,6 +294,7 @@ mod tests { r#"{"repeatedValue":["VALUE_B","VALUE_B","VALUE_A"]}"#, ); verify_decode(&decoded, r#"{"repeatedValue":[63,"VALUE_B","VALUE_A"]}"#); + verify_decode(&decoded, r#"{"repeated_value":[63,"VALUE_B","VALUE_A"]}"#); decoded.repeated_value = Default::default(); verify_decode(&decoded, "{}");