This is an automated email from the ASF dual-hosted git repository. kriskras99 pushed a commit to branch feat/enums in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit 7123747fff61b1993568640673384b378ee6863c Author: default <[email protected]> AuthorDate: Thu Mar 5 11:55:08 2026 +0000 more stuff --- avro_derive/src/lib.rs | 8 +- .../avro_rs_xxx_serde_from_into.expanded.rs | 153 ++++++++++++++++++++ .../{mod.rs => avro_rs_xxx_serde_from_into.rs} | 19 ++- .../avro_rs_xxx_serde_transparent.expanded.rs | 159 +++++++++++++++++++++ .../{mod.rs => avro_rs_xxx_serde_transparent.rs} | 23 ++- avro_derive/tests/expanded/mod.rs | 2 + .../avro_rs_xxx_serde_transparent_enum.rs} | 15 +- 7 files changed, 358 insertions(+), 21 deletions(-) diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs index a592f3a..d2f2a00 100644 --- a/avro_derive/src/lib.rs +++ b/avro_derive/src/lib.rs @@ -60,12 +60,14 @@ fn derive_avro_schema(input: DeriveInput) -> Result<TokenStream, Vec<syn::Error> let input_span = input.span(); let named_type_options = NamedTypeOptions::new(&input.ident, &input.attrs, input_span)?; if let Some(path) = named_type_options.with { + // `#[serde(into = "..", {try_,}from = ".."]` was specified. This means Serde will use the `Serialize`/`Deserialize` + // implementation of that type, so we also use the `AvroSchema` of that type. Ok(create_trait_definition( input.ident, &input.generics, - quote! { #path::get_schema_in_ctxt(named_schemas, enclosing_namespace) }, - quote! { #path::get_record_fields_in_ctxt(named_schemas, enclosing_namespace) }, - quote! { #path::field_default() }, + quote! { <#path as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, enclosing_namespace) }, + quote! { <#path as ::apache_avro::AvroSchemaComponent>::get_record_fields_in_ctxt(named_schemas, enclosing_namespace) }, + quote! { <#path as ::apache_avro::AvroSchemaComponent>::field_default() }, )) } else { match input.data { diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.expanded.rs b/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.expanded.rs new file mode 100644 index 0000000..83b87d8 --- /dev/null +++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.expanded.rs @@ -0,0 +1,153 @@ +use apache_avro::AvroSchema; +struct A { + a: i32, + b: String, +} +#[automatically_derived] +impl ::apache_avro::AvroSchemaComponent for A { + fn get_schema_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::apache_avro::schema::Schema { + let name = ::apache_avro::schema::Name::new_with_enclosing_namespace( + "A", + enclosing_namespace, + ) + .expect("Unable to parse schema name A"); + if named_schemas.contains(&name) { + ::apache_avro::schema::Schema::Ref { + name, + } + } else { + let enclosing_namespace = name.namespace(); + named_schemas.insert(name.clone()); + { + let mut schema_fields = ::std::vec::Vec::with_capacity(2usize); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "a".to_string(), + doc: ::std::option::Option::None, + default: <i32 as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <i32 as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "b".to_string(), + doc: ::std::option::Option::None, + default: <String as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <String as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + let schema_field_set: ::std::collections::HashSet<_> = schema_fields + .iter() + .map(|rf| &rf.name) + .collect(); + match (&schema_fields.len(), &schema_field_set.len()) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::Some( + format_args!( + "Duplicate field names found: {0:?}", schema_fields, + ), + ), + ); + } + } + }; + let name = ::apache_avro::schema::Name::new("A") + .expect( + &::alloc::__export::must_use({ + ::alloc::fmt::format( + format_args!( + "Unable to parse struct name for schema {0}", "A", + ), + ) + })[..], + ); + let lookup: ::std::collections::BTreeMap<String, usize> = schema_fields + .iter() + .enumerate() + .map(|(position, field)| (field.name.to_owned(), position)) + .collect(); + ::apache_avro::schema::Schema::Record(::apache_avro::schema::RecordSchema { + name, + aliases: ::std::option::Option::None, + doc: ::std::option::Option::None, + fields: schema_fields, + lookup, + attributes: ::std::collections::BTreeMap::new(), + }) + } + } + } + fn get_record_fields_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::std::option::Option<::std::vec::Vec<::apache_avro::schema::RecordField>> { + let mut schema_fields = Vec::with_capacity(2usize); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "a".to_string(), + doc: ::std::option::Option::None, + default: <i32 as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <i32 as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "b".to_string(), + doc: ::std::option::Option::None, + default: <String as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <String as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + Some(schema_fields) + } + fn field_default() -> ::std::option::Option<::serde_json::Value> { + ::std::option::Option::None + } +} +#[serde(into = "A", from = "A")] +struct B { + a: A, +} +#[automatically_derived] +impl ::apache_avro::AvroSchemaComponent for B { + fn get_schema_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::apache_avro::schema::Schema { + A::get_schema_in_ctxt(named_schemas, enclosing_namespace) + } + fn get_record_fields_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::std::option::Option<::std::vec::Vec<::apache_avro::schema::RecordField>> { + A::get_record_fields_in_ctxt(named_schemas, enclosing_namespace) + } + fn field_default() -> ::std::option::Option<::serde_json::Value> { + A::field_default() + } +} diff --git a/avro_derive/tests/expanded/mod.rs b/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.rs similarity index 74% copy from avro_derive/tests/expanded/mod.rs copy to avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.rs index 5715bfd..d440d3f 100644 --- a/avro_derive/tests/expanded/mod.rs +++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.rs @@ -1,3 +1,4 @@ +// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file @@ -14,10 +15,16 @@ // specific language governing permissions and limitations // under the License. -#![expect(dead_code, reason = "Only code generation is tested")] +use apache_avro::AvroSchema; -mod avro_3687_basic_enum_with_default; -mod avro_3709_record_field_attributes; -mod avro_rs_207_rename_all_attribute; -mod avro_rs_207_rename_attr_over_rename_all_attribute; -mod avro_rs_xxx_basic; +#[derive(AvroSchema)] +struct A { + a: i32, + b: String, +} + +#[derive(AvroSchema)] +#[serde(into = "A", from = "A")] +struct B { + a: A, +} diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs new file mode 100644 index 0000000..b85a630 --- /dev/null +++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs @@ -0,0 +1,159 @@ +use apache_avro::AvroSchema; +struct A { + a: i32, + b: String, +} +#[automatically_derived] +impl ::apache_avro::AvroSchemaComponent for A { + fn get_schema_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::apache_avro::schema::Schema { + let name = ::apache_avro::schema::Name::new_with_enclosing_namespace( + "A", + enclosing_namespace, + ) + .expect("Unable to parse schema name A"); + if named_schemas.contains(&name) { + ::apache_avro::schema::Schema::Ref { + name, + } + } else { + let enclosing_namespace = name.namespace(); + named_schemas.insert(name.clone()); + { + let mut schema_fields = ::std::vec::Vec::with_capacity(2usize); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "a".to_string(), + doc: ::std::option::Option::None, + default: <i32 as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <i32 as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "b".to_string(), + doc: ::std::option::Option::None, + default: <String as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <String as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + let schema_field_set: ::std::collections::HashSet<_> = schema_fields + .iter() + .map(|rf| &rf.name) + .collect(); + match (&schema_fields.len(), &schema_field_set.len()) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::Some( + format_args!( + "Duplicate field names found: {0:?}", schema_fields, + ), + ), + ); + } + } + }; + let name = ::apache_avro::schema::Name::new("A") + .expect( + &::alloc::__export::must_use({ + ::alloc::fmt::format( + format_args!( + "Unable to parse struct name for schema {0}", "A", + ), + ) + })[..], + ); + let lookup: ::std::collections::BTreeMap<String, usize> = schema_fields + .iter() + .enumerate() + .map(|(position, field)| (field.name.to_owned(), position)) + .collect(); + ::apache_avro::schema::Schema::Record(::apache_avro::schema::RecordSchema { + name, + aliases: ::std::option::Option::None, + doc: ::std::option::Option::None, + fields: schema_fields, + lookup, + attributes: ::std::collections::BTreeMap::new(), + }) + } + } + } + fn get_record_fields_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::std::option::Option<::std::vec::Vec<::apache_avro::schema::RecordField>> { + let mut schema_fields = Vec::with_capacity(2usize); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "a".to_string(), + doc: ::std::option::Option::None, + default: <i32 as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <i32 as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + schema_fields + .push(::apache_avro::schema::RecordField { + name: "b".to_string(), + doc: ::std::option::Option::None, + default: <String as ::apache_avro::AvroSchemaComponent>::field_default(), + aliases: ::std::vec::Vec::new(), + schema: <String as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ), + custom_attributes: ::std::collections::BTreeMap::new(), + }); + Some(schema_fields) + } + fn field_default() -> ::std::option::Option<::serde_json::Value> { + ::std::option::Option::None + } +} +#[serde(transparent)] +struct B { + a: A, +} +#[automatically_derived] +impl ::apache_avro::AvroSchemaComponent for B { + fn get_schema_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::apache_avro::schema::Schema { + <A as ::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt( + named_schemas, + enclosing_namespace, + ) + } + fn get_record_fields_in_ctxt( + named_schemas: &mut ::std::collections::HashSet<::apache_avro::schema::Name>, + enclosing_namespace: ::apache_avro::schema::NamespaceRef, + ) -> ::std::option::Option<::std::vec::Vec<::apache_avro::schema::RecordField>> { + <A as ::apache_avro::AvroSchemaComponent>::get_record_fields_in_ctxt( + named_schemas, + enclosing_namespace, + ) + } + fn field_default() -> ::std::option::Option<::serde_json::Value> { + ::std::option::Option::None + } +} diff --git a/avro_derive/tests/expanded/mod.rs b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs similarity index 72% copy from avro_derive/tests/expanded/mod.rs copy to avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs index 5715bfd..b23413b 100644 --- a/avro_derive/tests/expanded/mod.rs +++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs @@ -1,3 +1,4 @@ +// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file @@ -14,10 +15,20 @@ // specific language governing permissions and limitations // under the License. -#![expect(dead_code, reason = "Only code generation is tested")] +use apache_avro::AvroSchema; -mod avro_3687_basic_enum_with_default; -mod avro_3709_record_field_attributes; -mod avro_rs_207_rename_all_attribute; -mod avro_rs_207_rename_attr_over_rename_all_attribute; -mod avro_rs_xxx_basic; +#[derive(AvroSchema)] +struct A { + a: i32, + b: String, +} + +#[derive(AvroSchema)] +#[serde(transparent)] +struct B { + a: A, +} + +// #[derive(AvroSchema)] +// #[serde(transparent)] +// struct C(A); diff --git a/avro_derive/tests/expanded/mod.rs b/avro_derive/tests/expanded/mod.rs index 5715bfd..edea4cf 100644 --- a/avro_derive/tests/expanded/mod.rs +++ b/avro_derive/tests/expanded/mod.rs @@ -21,3 +21,5 @@ mod avro_3709_record_field_attributes; mod avro_rs_207_rename_all_attribute; mod avro_rs_207_rename_attr_over_rename_all_attribute; mod avro_rs_xxx_basic; +mod avro_rs_xxx_serde_from_into; +mod avro_rs_xxx_serde_transparent; diff --git a/avro_derive/tests/expanded/mod.rs b/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.rs similarity index 74% copy from avro_derive/tests/expanded/mod.rs copy to avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.rs index 5715bfd..19e483e 100644 --- a/avro_derive/tests/expanded/mod.rs +++ b/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.rs @@ -1,3 +1,4 @@ +// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file @@ -14,10 +15,12 @@ // specific language governing permissions and limitations // under the License. -#![expect(dead_code, reason = "Only code generation is tested")] +use apache_avro::AvroSchema; -mod avro_3687_basic_enum_with_default; -mod avro_3709_record_field_attributes; -mod avro_rs_207_rename_all_attribute; -mod avro_rs_207_rename_attr_over_rename_all_attribute; -mod avro_rs_xxx_basic; +#[derive(AvroSchema)] +#[serde(transparent)] +enum D { + A(A) +} + +pub fn main() {}
