From 8896d740a44ef46a3bad8cbfccedb87ea8e7b0d3 Mon Sep 17 00:00:00 2001 From: John Starks Date: Wed, 22 Feb 2023 13:01:41 -0800 Subject: [PATCH] fix: use correct Rust variant name for enum aliases This change fixes code generation of protobuf enums when aliases are present. --- pbjson-build/src/generator/enumeration.rs | 11 +++++++++-- pbjson-test/build.rs | 1 + pbjson-test/protos/enum_alias.proto | 12 ++++++++++++ pbjson-test/src/lib.rs | 5 +++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 pbjson-test/protos/enum_alias.proto diff --git a/pbjson-build/src/generator/enumeration.rs b/pbjson-build/src/generator/enumeration.rs index 05850af..6aa3105 100644 --- a/pbjson-build/src/generator/enumeration.rs +++ b/pbjson-build/src/generator/enumeration.rs @@ -11,6 +11,7 @@ use super::{ use crate::descriptor::{EnumDescriptor, TypePath}; use crate::generator::write_fields_array; use crate::resolver::Resolver; +use std::collections::HashMap; use std::io::{Result, Write}; pub fn generate_enum( @@ -22,19 +23,25 @@ pub fn generate_enum( ) -> Result<()> { let rust_type = resolver.rust_type(path); + let mut rust_variants = HashMap::new(); let variants: Vec<_> = descriptor .values .iter() .map(|variant| { let variant_name = variant.name.clone().unwrap(); let variant_number = variant.number(); - let rust_variant = resolver.rust_variant(path, &variant_name); - (variant_name, variant_number, rust_variant) + let rust_variant = rust_variants + .entry(variant_number) + .or_insert_with(|| resolver.rust_variant(path, &variant_name)); + (variant_name, variant_number, rust_variant.clone()) }) .collect(); // Generate Serialize write_serialize_start(0, &rust_type, writer)?; + // There will be duplicates in the presense of aliases. Let rustc deal with + // this. + writeln!(writer, "{}#[allow(unreachable_patterns)]", Indent(2))?; if use_integers_for_enums { writeln!(writer, "{}let variant = match self {{", Indent(2))?; for (_, variant_number, rust_variant) in &variants { diff --git a/pbjson-test/build.rs b/pbjson-test/build.rs index 02bd410..af66627 100644 --- a/pbjson-test/build.rs +++ b/pbjson-test/build.rs @@ -14,6 +14,7 @@ fn main() -> Result<()> { root.join("common.proto"), root.join("duplicate_name.proto"), root.join("escape.proto"), + root.join("enum_alias.proto"), ]; // Tell cargo to recompile if any of these proto files are changed diff --git a/pbjson-test/protos/enum_alias.proto b/pbjson-test/protos/enum_alias.proto new file mode 100644 index 0000000..c857259 --- /dev/null +++ b/pbjson-test/protos/enum_alias.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package test.enum_alias; + +enum Enum { + option allow_alias = true; + VALUE = 0; + OTHER = 1; + TWO = 2; + DOS = 2; + value = 0; + alias = 0; +} diff --git a/pbjson-test/src/lib.rs b/pbjson-test/src/lib.rs index a2f604a..0b0fcf8 100644 --- a/pbjson-test/src/lib.rs +++ b/pbjson-test/src/lib.rs @@ -49,6 +49,11 @@ pub mod test { "/test.r#abstract.r#type.escape.serde.rs" )); } + + pub mod enum_alias { + include!(concat!(env!("OUT_DIR"), "/test.enum_alias.rs")); + include!(concat!(env!("OUT_DIR"), "/test.enum_alias.serde.rs")); + } } #[cfg(test)]