diff --git a/serde-generate/src/dart.rs b/serde-generate/src/dart.rs index 32506c2a2..595092f48 100644 --- a/serde-generate/src/dart.rs +++ b/serde-generate/src/dart.rs @@ -1047,6 +1047,42 @@ switch (this) {{"#, self.enter_class(name); writeln!(self.out, "const {}();", self.quote_qualified_name(name))?; + // if all variants are structs, output base class getters for properties that + // have the same name and type across every variant + let shared_fields = + variants + .values() + .enumerate() + .fold(vec![], |shared_fields, enumerated_variant| { + if let VariantFormat::Struct(fields) = &enumerated_variant.1.value { + if enumerated_variant.0 == 0 { + let mut cp = fields.to_vec(); + cp.sort_by_key(|field| field.name.to_owned()); + cp + } else { + shared_fields + .into_iter() + .filter(|field| fields.contains(field)) + .collect() + } + } else { + vec![] + } + }); + + if !shared_fields.is_empty() { + writeln!(self.out)?; + } + + for field in &shared_fields { + writeln!( + self.out, + "{} get {};", + self.quote_type(&field.value), + self.quote_field(&field.name.to_mixed_case()), + )?; + } + if self.generator.config.serialization { writeln!(self.out, "\nvoid serialize(BinarySerializer serializer);")?; write!( diff --git a/serde-generate/src/test_utils.rs b/serde-generate/src/test_utils.rs index db713ac70..9755e60ca 100644 --- a/serde-generate/src/test_utils.rs +++ b/serde-generate/src/test_utils.rs @@ -119,6 +119,25 @@ pub struct Tree { #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct SimpleList(Option>); +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub enum ComplexEnum { + A { + id: String, + value: String, + a: String, + }, + B { + id: String, + value: i32, + b: String, + }, + C { + id: String, + value: bool, + c: String, + }, +} + #[derive(Debug, Serialize, Deserialize, PartialEq)] pub enum CStyleEnum { A, @@ -135,6 +154,7 @@ pub fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::>(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.registry() } @@ -653,6 +673,26 @@ CStyleEnum: D: UNIT 4: E: UNIT +ComplexEnum: + ENUM: + 0: + A: + STRUCT: + - id: STR + - value: STR + - a: STR + 1: + B: + STRUCT: + - id: STR + - value: I32 + - b: STR + 2: + C: + STRUCT: + - id: STR + - value: BOOL + - c: STR List: ENUM: 0: diff --git a/serde-generate/tests/analyzer.rs b/serde-generate/tests/analyzer.rs index 7cf5304d9..c6f295f39 100644 --- a/serde-generate/tests/analyzer.rs +++ b/serde-generate/tests/analyzer.rs @@ -91,7 +91,8 @@ fn test_on_larger_registry() { "Tree", "TupleStruct", "UnitStruct", - "SerdeData" + "SerdeData", + "ComplexEnum", ] ); } diff --git a/serde-generate/tests/dart_generation.rs b/serde-generate/tests/dart_generation.rs index ecc49d9eb..112c3fb60 100644 --- a/serde-generate/tests/dart_generation.rs +++ b/serde-generate/tests/dart_generation.rs @@ -122,3 +122,29 @@ fn test_dart_code_compiles_class_enums_for_complex_enums() { assert!(generated_c_style.contains("enum CStyleEnum {")); assert!(generated_class_style.contains("abstract class List_ {")); } + +#[test] +fn test_dart_code_includes_getters_for_shared_properties_of_complex_enums() { + let source_path = tempdir() + .unwrap() + .path() + .join("dart_class_enum_shared_properties_project"); + + let config = CodeGeneratorConfig::new("example".to_string()) + .with_encodings(vec![Encoding::Bcs, Encoding::Bincode]) + // we enable native Dart enums to test that complex Rust enums will still produce Dart classes + .with_c_style_enums(true); + + generate_with_config(source_path.clone(), &config); + + let generated_class_style = + read_to_string(&source_path.join("lib/src/example/complex_enum.dart")).unwrap(); + + assert!(generated_class_style.contains("String get id;\n")); + assert!(!generated_class_style.contains("String get value;\n")); + assert!(!generated_class_style.contains("int get value;\n")); + assert!(!generated_class_style.contains("bool get value;\n")); + assert!(!generated_class_style.contains("String get a;\n")); + assert!(!generated_class_style.contains("String get b;\n")); + assert!(!generated_class_style.contains("String get c;\n")); +}