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/02/25 21:12:50 UTC

(avro-rs) branch chore/avro_derive_enum_module created (now 1a3ad2c)

This is an automated email from the ASF dual-hosted git repository.

kriskras99 pushed a change to branch chore/avro_derive_enum_module
in repository https://gitbox.apache.org/repos/asf/avro-rs.git


      at 1a3ad2c  chore: Move enum derive to `enums::plain` in `avro_derive`

This branch includes the following new commits:

     new 1a3ad2c  chore: Move enum derive to `enums::plain` in `avro_derive`

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(avro-rs) 01/01: chore: Move enum derive to `enums::plain` in `avro_derive`

Posted by kr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kriskras99 pushed a commit to branch chore/avro_derive_enum_module
in repository https://gitbox.apache.org/repos/asf/avro-rs.git

commit 1a3ad2c8d06c3726af93d7a897db124246cbf8d6
Author: Kriskras99 <gi...@kriskras99.nl>
AuthorDate: Wed Feb 25 22:11:41 2026 +0100

    chore: Move enum derive to `enums::plain` in `avro_derive`
    
    Prep for more complete enum support
---
 avro_derive/src/enums/mod.rs   | 50 +++++++++++++++++++++++++++
 avro_derive/src/enums/plain.rs | 49 +++++++++++++++++++++++++++
 avro_derive/src/lib.rs         | 77 +++---------------------------------------
 3 files changed, 103 insertions(+), 73 deletions(-)

diff --git a/avro_derive/src/enums/mod.rs b/avro_derive/src/enums/mod.rs
new file mode 100644
index 0000000..9613124
--- /dev/null
+++ b/avro_derive/src/enums/mod.rs
@@ -0,0 +1,50 @@
+mod plain;
+
+use crate::attributes::NamedTypeOptions;
+use proc_macro2::{Ident, Span, TokenStream};
+use syn::{Attribute, DataEnum, Fields, Meta};
+
+/// Generate a schema definition for a enum.
+pub fn get_data_enum_schema_def(
+    container_attrs: &NamedTypeOptions,
+    data_enum: DataEnum,
+    ident_span: Span,
+) -> Result<TokenStream, Vec<syn::Error>> {
+    if data_enum.variants.iter().all(|v| Fields::Unit == v.fields) {
+        plain::schema_def(container_attrs, data_enum, ident_span)
+    } else {
+        Err(vec![syn::Error::new(
+            ident_span,
+            "AvroSchema: derive does not work for enums with non unit structs",
+        )])
+    }
+}
+
+fn default_enum_variant(
+    data_enum: &DataEnum,
+    error_span: Span,
+) -> Result<Option<String>, Vec<syn::Error>> {
+    match data_enum
+        .variants
+        .iter()
+        .filter(|v| v.attrs.iter().any(is_default_attr))
+        .collect::<Vec<_>>()
+    {
+        variants if variants.is_empty() => Ok(None),
+        single if single.len() == 1 => Ok(Some(single[0].ident.to_string())),
+        multiple => Err(vec![syn::Error::new(
+            error_span,
+            format!(
+                "Multiple defaults defined: {:?}",
+                multiple
+                    .iter()
+                    .map(|v| v.ident.to_string())
+                    .collect::<Vec<String>>()
+            ),
+        )]),
+    }
+}
+
+fn is_default_attr(attr: &Attribute) -> bool {
+    matches!(attr, Attribute { meta: Meta::Path(path), .. } if path.get_ident().map(Ident::to_string).as_deref() == Some("default"))
+}
diff --git a/avro_derive/src/enums/plain.rs b/avro_derive/src/enums/plain.rs
new file mode 100644
index 0000000..cc77c7b
--- /dev/null
+++ b/avro_derive/src/enums/plain.rs
@@ -0,0 +1,49 @@
+use crate::attributes::{NamedTypeOptions, VariantOptions};
+use crate::case::RenameRule;
+use crate::enums::default_enum_variant;
+use crate::{aliases, preserve_optional};
+use proc_macro2::{Span, TokenStream};
+use quote::quote;
+use syn::spanned::Spanned;
+use syn::{DataEnum, Fields};
+
+pub fn schema_def(
+    container_attrs: &NamedTypeOptions,
+    data_enum: DataEnum,
+    ident_span: Span,
+) -> Result<TokenStream, Vec<syn::Error>> {
+    let doc = preserve_optional(container_attrs.doc.as_ref());
+    let enum_aliases = aliases(&container_attrs.aliases);
+    if data_enum.variants.iter().all(|v| Fields::Unit == v.fields) {
+        let default_value = default_enum_variant(&data_enum, ident_span)?;
+        let default = preserve_optional(default_value);
+        let mut symbols = Vec::new();
+        for variant in &data_enum.variants {
+            let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
+            let name = match (field_attrs.rename, container_attrs.rename_all) {
+                (Some(rename), _) => rename,
+                (None, rename_all) if !matches!(rename_all, RenameRule::None) => {
+                    rename_all.apply_to_variant(&variant.ident.to_string())
+                }
+                _ => variant.ident.to_string(),
+            };
+            symbols.push(name);
+        }
+        let full_schema_name = &container_attrs.name;
+        Ok(quote! {
+            ::apache_avro::schema::Schema::Enum(apache_avro::schema::EnumSchema {
+                name: ::apache_avro::schema::Name::new(#full_schema_name).expect(&format!("Unable to parse enum name for schema {}", #full_schema_name)[..]),
+                aliases: #enum_aliases,
+                doc: #doc,
+                symbols: vec![#(#symbols.to_owned()),*],
+                default: #default,
+                attributes: Default::default(),
+            })
+        })
+    } else {
+        Err(vec![syn::Error::new(
+            ident_span,
+            "AvroSchema: derive does not work for enums with non unit structs",
+        )])
+    }
+}
diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs
index d6562c8..8e590eb 100644
--- a/avro_derive/src/lib.rs
+++ b/avro_derive/src/lib.rs
@@ -31,16 +31,18 @@
 
 mod attributes;
 mod case;
+mod enums;
 
 use proc_macro2::{Span, TokenStream};
 use quote::quote;
 use syn::{
-    Attribute, DataEnum, DataStruct, DeriveInput, Expr, Field, Fields, Generics, Ident, Meta, Type,
+    DataStruct, DeriveInput, Expr, Field, Fields, Generics, Ident, Type,
     parse_macro_input, spanned::Spanned,
 };
 
+use crate::enums::get_data_enum_schema_def;
 use crate::{
-    attributes::{FieldDefault, FieldOptions, NamedTypeOptions, VariantOptions, With},
+    attributes::{FieldDefault, FieldOptions, NamedTypeOptions, With},
     case::RenameRule,
 };
 
@@ -383,48 +385,6 @@ fn get_field_get_record_fields_expr(
     }
 }
 
-/// Generate a schema definition for a enum.
-fn get_data_enum_schema_def(
-    container_attrs: &NamedTypeOptions,
-    data_enum: DataEnum,
-    ident_span: Span,
-) -> Result<TokenStream, Vec<syn::Error>> {
-    let doc = preserve_optional(container_attrs.doc.as_ref());
-    let enum_aliases = aliases(&container_attrs.aliases);
-    if data_enum.variants.iter().all(|v| Fields::Unit == v.fields) {
-        let default_value = default_enum_variant(&data_enum, ident_span)?;
-        let default = preserve_optional(default_value);
-        let mut symbols = Vec::new();
-        for variant in &data_enum.variants {
-            let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
-            let name = match (field_attrs.rename, container_attrs.rename_all) {
-                (Some(rename), _) => rename,
-                (None, rename_all) if !matches!(rename_all, RenameRule::None) => {
-                    rename_all.apply_to_variant(&variant.ident.to_string())
-                }
-                _ => variant.ident.to_string(),
-            };
-            symbols.push(name);
-        }
-        let full_schema_name = &container_attrs.name;
-        Ok(quote! {
-            ::apache_avro::schema::Schema::Enum(apache_avro::schema::EnumSchema {
-                name: ::apache_avro::schema::Name::new(#full_schema_name).expect(&format!("Unable to parse enum name for schema {}", #full_schema_name)[..]),
-                aliases: #enum_aliases,
-                doc: #doc,
-                symbols: vec![#(#symbols.to_owned()),*],
-                default: #default,
-                attributes: Default::default(),
-            })
-        })
-    } else {
-        Err(vec![syn::Error::new(
-            ident_span,
-            "AvroSchema: derive does not work for enums with non unit structs",
-        )])
-    }
-}
-
 /// Takes in the Tokens of a type and returns the tokens of an expression with return type `Schema`
 fn type_to_schema_expr(ty: &Type) -> Result<TokenStream, Vec<syn::Error>> {
     match ty {
@@ -492,35 +452,6 @@ fn type_to_field_default_expr(ty: &Type) -> Result<TokenStream, Vec<syn::Error>>
     }
 }
 
-fn default_enum_variant(
-    data_enum: &syn::DataEnum,
-    error_span: Span,
-) -> Result<Option<String>, Vec<syn::Error>> {
-    match data_enum
-        .variants
-        .iter()
-        .filter(|v| v.attrs.iter().any(is_default_attr))
-        .collect::<Vec<_>>()
-    {
-        variants if variants.is_empty() => Ok(None),
-        single if single.len() == 1 => Ok(Some(single[0].ident.to_string())),
-        multiple => Err(vec![syn::Error::new(
-            error_span,
-            format!(
-                "Multiple defaults defined: {:?}",
-                multiple
-                    .iter()
-                    .map(|v| v.ident.to_string())
-                    .collect::<Vec<String>>()
-            ),
-        )]),
-    }
-}
-
-fn is_default_attr(attr: &Attribute) -> bool {
-    matches!(attr, Attribute { meta: Meta::Path(path), .. } if path.get_ident().map(Ident::to_string).as_deref() == Some("default"))
-}
-
 /// Stolen from serde
 fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
     let compile_errors = errors.iter().map(syn::Error::to_compile_error);