You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by kr...@apache.org on 2026/03/06 10:26:51 UTC
(avro-rs) 02/04: more stuff
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 e9c13f281542be0d9917a1bdf93d5f65ca7b050e
Author: default <ad...@kriskras99.nl>
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} | 21 +--
.../avro_rs_xxx_serde_transparent.expanded.rs | 159 +++++++++++++++++++++
.../{mod.rs => avro_rs_xxx_serde_transparent.rs} | 25 ++--
avro_derive/tests/expanded/mod.rs | 2 +
.../avro_rs_xxx_serde_transparent_enum.rs} | 17 +--
7 files changed, 352 insertions(+), 33 deletions(-)
diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs
index f15cb59..36836a4 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 65%
copy from avro_derive/tests/expanded/mod.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.rs
index adaa76a..d440d3f 100644
--- a/avro_derive/tests/expanded/mod.rs
+++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_from_into.rs
@@ -15,15 +15,16 @@
// specific language governing permissions and limitations
// under the License.
-#![expect(dead_code, reason = "Only code generation is tested")]
+use apache_avro::AvroSchema;
-// Do not include the `.expanded` modules here, as that code won't compile
+#[derive(AvroSchema)]
+struct A {
+ a: i32,
+ b: String,
+}
-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_501_basic;
-mod avro_rs_501_namespace;
-mod avro_rs_501_reference;
-mod avro_rs_501_struct_with_optional;
+#[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 65%
copy from avro_derive/tests/expanded/mod.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
index adaa76a..b23413b 100644
--- a/avro_derive/tests/expanded/mod.rs
+++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
@@ -15,15 +15,20 @@
// specific language governing permissions and limitations
// under the License.
-#![expect(dead_code, reason = "Only code generation is tested")]
+use apache_avro::AvroSchema;
-// Do not include the `.expanded` modules here, as that code won't compile
+#[derive(AvroSchema)]
+struct A {
+ a: i32,
+ b: String,
+}
-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_501_basic;
-mod avro_rs_501_namespace;
-mod avro_rs_501_reference;
-mod avro_rs_501_struct_with_optional;
+#[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 adaa76a..b661b4d 100644
--- a/avro_derive/tests/expanded/mod.rs
+++ b/avro_derive/tests/expanded/mod.rs
@@ -27,3 +27,5 @@ mod avro_rs_501_basic;
mod avro_rs_501_namespace;
mod avro_rs_501_reference;
mod avro_rs_501_struct_with_optional;
+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 65%
copy from avro_derive/tests/expanded/mod.rs
copy to avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.rs
index adaa76a..19e483e 100644
--- a/avro_derive/tests/expanded/mod.rs
+++ b/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.rs
@@ -15,15 +15,12 @@
// specific language governing permissions and limitations
// under the License.
-#![expect(dead_code, reason = "Only code generation is tested")]
+use apache_avro::AvroSchema;
-// Do not include the `.expanded` modules here, as that code won't compile
+#[derive(AvroSchema)]
+#[serde(transparent)]
+enum D {
+ A(A)
+}
-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_501_basic;
-mod avro_rs_501_namespace;
-mod avro_rs_501_reference;
-mod avro_rs_501_struct_with_optional;
+pub fn main() {}