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 101c8c30736385286556b6688942de45bcfa9225
Author: default <[email protected]>
AuthorDate: Thu Mar 5 19:57:24 2026 +0000

    more testing
---
 avro_derive/src/attributes/mod.rs                  |  25 ++-
 avro_derive/src/enums/bare_union.rs                |  44 +---
 avro_derive/src/enums/record_internally_tagged.rs  |  20 +-
 avro_derive/src/enums/record_tag_content.rs        |  43 +---
 avro_derive/src/enums/union_of_records.rs          |  53 +----
 avro_derive/src/lib.rs                             | 222 +++++++++----------
 avro_derive/src/tuple.rs                           |  59 +++++
 .../avro_3709_record_field_attributes.expanded.rs  |   4 +-
 .../expanded/avro_rs_xxx_bare_union.expanded.rs    | 239 +++++++++++++++++++++
 ...de_transparent.rs => avro_rs_xxx_bare_union.rs} |  31 +--
 ...s => avro_rs_xxx_internally_tagged.expanded.rs} |   0
 ...sparent.rs => avro_rs_xxx_internally_tagged.rs} |   0
 .../avro_rs_xxx_serde_from_into.expanded.rs        |  12 +-
 .../avro_rs_xxx_serde_transparent.expanded.rs      |  26 +++
 .../expanded/avro_rs_xxx_serde_transparent.rs      |   6 +-
 ...nded.rs => avro_rs_xxx_tag_content.expanded.rs} |   0
 ...e_transparent.rs => avro_rs_xxx_tag_content.rs} |   0
 ...rs => avro_rs_xxx_union_of_records.expanded.rs} |   0
 ...nsparent.rs => avro_rs_xxx_union_of_records.rs} |   0
 avro_derive/tests/expanded/mod.rs                  |   4 +
 .../avro_rs_xxx_bare_union_and_untagged.rs}        |  25 ++-
 .../ui/avro_rs_xxx_bare_union_and_untagged.stderr  |  20 ++
 .../ui/avro_rs_xxx_serde_transparent_enum.stderr   |   8 +
 23 files changed, 553 insertions(+), 288 deletions(-)

diff --git a/avro_derive/src/attributes/mod.rs 
b/avro_derive/src/attributes/mod.rs
index 21fe772..ce609cd 100644
--- a/avro_derive/src/attributes/mod.rs
+++ b/avro_derive/src/attributes/mod.rs
@@ -15,11 +15,11 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::case::RenameRule;
+use crate::{case::RenameRule, type_to_field_default_expr};
 use darling::{FromAttributes, FromMeta};
 use proc_macro2::{Span, TokenStream};
 use quote::quote;
-use syn::{AttrStyle, Attribute, Expr, Ident, Path, spanned::Spanned};
+use syn::{AttrStyle, Attribute, Expr, Ident, Path, Type, spanned::Spanned};
 
 mod avro;
 mod serde;
@@ -389,6 +389,27 @@ pub enum FieldDefault {
     Value(String),
 }
 
+impl FieldDefault {
+    pub fn into_tokenstream(self, span: Span, field_type: &Type) -> 
Result<TokenStream, Vec<syn::Error>> {
+        match self {
+            FieldDefault::Disabled => Ok(quote! { None }),
+            FieldDefault::Trait => type_to_field_default_expr(field_type),
+            FieldDefault::Value(default_value) => {
+                let _: serde_json::Value = 
serde_json::from_str(&default_value[..])
+                    .map_err(|e| {
+                        vec![syn::Error::new(
+                            span,
+                            format!("Invalid avro default json: \n{e}"),
+                        )]
+                    })?;
+                Ok(quote! {
+                    
Some(::serde_json::from_str(#default_value).expect(format!("Invalid JSON: 
{:?}", #default_value).as_str()))
+                })
+            }
+        }
+    }
+}
+
 impl FromMeta for FieldDefault {
     fn from_string(value: &str) -> darling::Result<Self> {
         Ok(Self::Value(value.to_string()))
diff --git a/avro_derive/src/enums/bare_union.rs 
b/avro_derive/src/enums/bare_union.rs
index b0342b2..3385343 100644
--- a/avro_derive/src/enums/bare_union.rs
+++ b/avro_derive/src/enums/bare_union.rs
@@ -1,5 +1,6 @@
 use crate::attributes::{NamedTypeOptions, VariantOptions};
-use crate::type_to_schema_expr;
+use crate::tuple::tuple_to_record_schema;
+use crate::{named_to_record_fields, type_to_schema_expr};
 use proc_macro2::{Span, TokenStream};
 use quote::quote;
 use syn::spanned::Spanned;
@@ -13,28 +14,15 @@ pub fn get_data_enum_schema_def(
     let mut variant_expr = Vec::new();
     let mut have_null = false;
     for variant in data_enum.variants {
-        let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
-        let name = field_attrs.rename.unwrap_or_else(|| {
+        let variant_attrs = VariantOptions::new(&variant.attrs, 
variant.span())?;
+        let name = variant_attrs.rename.unwrap_or_else(|| {
             container_attrs
                 .rename_all
                 .apply_to_variant(&variant.ident.to_string())
         });
         match variant.fields {
             Fields::Named(named) => {
-                let mut fields = Vec::with_capacity(named.named.len());
-                for field in named.named {
-                    let ident = field_attrs
-                        .rename_all
-                        .or(container_attrs.rename_all_fields)
-                        .apply_to_field(&field.ident.unwrap().to_string());
-                    let schema_expr = type_to_schema_expr(&field.ty)?;
-                    fields.push(quote! {
-                        ::apache_avro::schema::RecordField::builder()
-                            .name(#ident.to_string())
-                            .schema(#schema_expr)
-                            .build()
-                    });
-                }
+                let fields = named_to_record_fields(named, 
variant_attrs.rename_all.or(container_attrs.rename_all_fields))?;
 
                 let schema_expr = quote! {
                     ::apache_avro::schema::Schema::Record(
@@ -59,28 +47,8 @@ pub fn get_data_enum_schema_def(
                     let schema_expr = type_to_schema_expr(&only_one.ty)?;
                     variant_expr.push(schema_expr);
                 } else if unnamed.unnamed.len() > 1 {
-                    let mut fields = Vec::with_capacity(unnamed.unnamed.len());
-                    for (index, field) in unnamed.unnamed.iter().enumerate() {
-                        let field_schema_expr = 
type_to_schema_expr(&field.ty)?;
-                        fields.push(quote! {
-                            ::apache_avro::schema::RecordField::builder()
-                                .name(format!("field_{}", #index))
-                                .schema(#field_schema_expr)
-                                .build()
-                        });
-                    }
+                    let schema_expr = tuple_to_record_schema(unnamed, &name, 
&[])?;
 
-                    let schema_expr = quote! {
-                        ::apache_avro::schema::Schema::Record(
-                            ::apache_avro::schema::RecordSchema::builder()
-                                
.name(::apache_avro::schema::Name::new_with_enclosing_namespace(#name, 
enclosing_namespace).expect(&format!("Unable to parse variant record name for 
schema {}", #name)[..]))
-                                .fields(vec![
-                                    #(#fields,)*
-                                ])
-                                
.attributes([("org.apache.avro.rust.tuple".to_string(), 
::serde_json::value::Value::Bool(true))].into())
-                                .build()
-                        )
-                    };
                     variant_expr.push(schema_expr);
                 }
             }
diff --git a/avro_derive/src/enums/record_internally_tagged.rs 
b/avro_derive/src/enums/record_internally_tagged.rs
index f3331dc..8c3c76e 100644
--- a/avro_derive/src/enums/record_internally_tagged.rs
+++ b/avro_derive/src/enums/record_internally_tagged.rs
@@ -1,5 +1,5 @@
 use crate::attributes::{NamedTypeOptions, VariantOptions};
-use crate::{aliases, preserve_optional, type_to_schema_expr};
+use crate::{aliases, named_to_record_fields, preserve_optional, 
type_to_schema_expr};
 use proc_macro2::TokenStream;
 use quote::quote;
 use syn::spanned::Spanned;
@@ -15,27 +15,15 @@ pub fn get_data_enum_schema_def(
     let mut symbols = Vec::new();
     let mut field_additions = Vec::new();
     for variant in data_enum.variants {
-        let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
-        let name = field_attrs.rename.unwrap_or_else(|| {
+        let variant_attrs = VariantOptions::new(&variant.attrs, 
variant.span())?;
+        let name = variant_attrs.rename.unwrap_or_else(|| {
             container_attrs
                 .rename_all
                 .apply_to_variant(&variant.ident.to_string())
         });
         match variant.fields {
             Fields::Named(named) => {
-                for field in named.named {
-                    let ident = field_attrs
-                        .rename_all
-                        .or(container_attrs.rename_all_fields)
-                        .apply_to_field(&field.ident.unwrap().to_string());
-                    let schema_expr = type_to_schema_expr(&field.ty)?;
-                    field_additions.push(quote! {
-                        
fields.push(::apache_avro::schema::RecordField::builder()
-                            .name(#ident.to_string())
-                            .schema(#schema_expr)
-                            .build())
-                    });
-                }
+                field_additions.extend(named_to_record_fields(named, 
variant_attrs.rename_all.or(container_attrs.rename_all_fields))?);
             }
             Fields::Unnamed(unnamed) => {
                 if unnamed.unnamed.len() == 1 {
diff --git a/avro_derive/src/enums/record_tag_content.rs 
b/avro_derive/src/enums/record_tag_content.rs
index 5227de2..c02eca9 100644
--- a/avro_derive/src/enums/record_tag_content.rs
+++ b/avro_derive/src/enums/record_tag_content.rs
@@ -1,5 +1,6 @@
 use crate::attributes::{NamedTypeOptions, VariantOptions};
-use crate::{aliases, preserve_optional, type_to_schema_expr};
+use crate::tuple::tuple_to_record_schema;
+use crate::{aliases, named_to_record_fields, preserve_optional, 
type_to_schema_expr};
 use proc_macro2::TokenStream;
 use quote::quote;
 use syn::spanned::Spanned;
@@ -16,28 +17,15 @@ pub fn get_data_enum_schema_def(
     let mut symbols = Vec::new();
     let mut schema_definitions = Vec::new();
     for variant in data_enum.variants {
-        let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
-        let name = field_attrs.rename.unwrap_or_else(|| {
+        let variant_attrs = VariantOptions::new(&variant.attrs, 
variant.span())?;
+        let name = variant_attrs.rename.unwrap_or_else(|| {
             container_attrs
                 .rename_all
                 .apply_to_variant(&variant.ident.to_string())
         });
         match variant.fields {
             Fields::Named(named) => {
-                let mut fields = Vec::with_capacity(named.named.len());
-                for field in named.named {
-                    let ident = field_attrs
-                        .rename_all
-                        .or(container_attrs.rename_all_fields)
-                        .apply_to_field(&field.ident.unwrap().to_string());
-                    let schema_expr = type_to_schema_expr(&field.ty)?;
-                    fields.push(quote! {
-                        ::apache_avro::schema::RecordField::builder()
-                            .name(#ident.to_string())
-                            .schema(#schema_expr)
-                            .build()
-                    });
-                }
+                let fields = named_to_record_fields(named, 
variant_attrs.rename_all.or(container_attrs.rename_all_fields))?;
 
                 let schema_expr = quote! {
                     ::apache_avro::schema::Schema::Record(
@@ -62,27 +50,8 @@ pub fn get_data_enum_schema_def(
                     let field_schema_expr = type_to_schema_expr(&only_one.ty)?;
                     schema_definitions.push(field_schema_expr);
                 } else if unnamed.unnamed.len() > 1 {
-                    let mut fields = Vec::with_capacity(unnamed.unnamed.len());
-                    for (index, field) in unnamed.unnamed.iter().enumerate() {
-                        let field_schema_expr = 
type_to_schema_expr(&field.ty)?;
-                        fields.push(quote! {
-                            ::apache_avro::schema::RecordField::builder()
-                                .name(format!("field_{}", #index))
-                                .schema(#field_schema_expr)
-                                .build()
-                        });
-                    }
+                    let schema_expr = tuple_to_record_schema(unnamed, &name, 
&[])?;
 
-                    let schema_expr = quote! {
-                        ::apache_avro::schema::Schema::Record(
-                            ::apache_avro::schema::RecordSchema::builder()
-                                
.name(::apache_avro::schema::Name::new_with_enclosing_namespace(#name, 
enclosing_namespace).expect(&format!("Unable to parse variant record name for 
schema {}", #name)[..]))
-                                .fields(vec![
-                                    #(#fields,)*
-                                ])
-                                .build()
-                        )
-                    };
                     schema_definitions.push(schema_expr);
                 }
             }
diff --git a/avro_derive/src/enums/union_of_records.rs 
b/avro_derive/src/enums/union_of_records.rs
index 4a68a0e..44a853c 100644
--- a/avro_derive/src/enums/union_of_records.rs
+++ b/avro_derive/src/enums/union_of_records.rs
@@ -1,5 +1,6 @@
 use crate::attributes::{NamedTypeOptions, VariantOptions};
-use crate::type_to_schema_expr;
+use crate::tuple::tuple_to_record_schema;
+use crate::{named_to_record_fields};
 use proc_macro2::TokenStream;
 use quote::quote;
 use syn::spanned::Spanned;
@@ -11,28 +12,15 @@ pub fn get_data_enum_schema_def(
 ) -> Result<TokenStream, Vec<syn::Error>> {
     let mut variant_expr = Vec::new();
     for variant in data_enum.variants {
-        let field_attrs = VariantOptions::new(&variant.attrs, variant.span())?;
-        let name = field_attrs.rename.unwrap_or_else(|| {
+        let variant_attrs = VariantOptions::new(&variant.attrs, 
variant.span())?;
+        let name = variant_attrs.rename.unwrap_or_else(|| {
             container_attrs
                 .rename_all
                 .apply_to_variant(&variant.ident.to_string())
         });
         match variant.fields {
             Fields::Named(named) => {
-                let mut fields = Vec::with_capacity(named.named.len());
-                for field in named.named {
-                    let ident = field_attrs
-                        .rename_all
-                        .or(container_attrs.rename_all_fields)
-                        .apply_to_field(&field.ident.unwrap().to_string());
-                    let schema_expr = type_to_schema_expr(&field.ty)?;
-                    fields.push(quote! {
-                        ::apache_avro::schema::RecordField::builder()
-                            .name(#ident.to_string())
-                            .schema(#schema_expr)
-                            .build()
-                    });
-                }
+                let fields = named_to_record_fields(named, 
variant_attrs.rename_all.or(container_attrs.rename_all_fields))?;
 
                 let schema_expr = quote! {
                     ::apache_avro::schema::Schema::Record(
@@ -47,33 +35,12 @@ pub fn get_data_enum_schema_def(
                 variant_expr.push(schema_expr);
             }
             Fields::Unnamed(unnamed) => {
-                let mut fields = Vec::with_capacity(unnamed.unnamed.len());
-                for (index, field) in unnamed.unnamed.iter().enumerate() {
-                    let field_schema_expr = type_to_schema_expr(&field.ty)?;
-                    fields.push(quote! {
-                        ::apache_avro::schema::RecordField::builder()
-                            .name(format!("field_{}", #index))
-                            .schema(#field_schema_expr)
-                            .build()
-                    });
-                }
-
-                let amount_of_fields = unnamed.unnamed.len();
-
-                let schema_expr = quote! {
-                    let mut builder = 
::apache_avro::schema::RecordSchema::builder()
-                            
.name(::apache_avro::schema::Name::new_with_enclosing_namespace(#name, 
enclosing_namespace).expect(&format!("Unable to parse variant record name for 
schema {}", #name)[..]))
-                            .fields(vec![
-                                #(#fields,)*
-                            ]);
-                    if #amount_of_fields == 1 {
-                        builder = 
builder.attributes([("org.apache.avro.rust.union_of_records".to_string(), 
::serde_json::value::Value::Bool(true))].into());
-                    } else if #amount_of_fields > 1 {
-                        builder = 
builder.attributes([("org.apache.avro.rust.tuple".to_string(), 
::serde_json::value::Value::Bool(true))].into());
-                    }
-
-                    ::apache_avro::schema::Schema::Record(builder.build())
+                let schema_expr = if unnamed.unnamed.len() == 1 {
+                    tuple_to_record_schema(unnamed, &name, 
&["org.apache.avro.rust.union_of_records"])?
+                } else {
+                    tuple_to_record_schema(unnamed, &name, &[])?
                 };
+
                 variant_expr.push(schema_expr);
             }
             Fields::Unit => {
diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs
index d2f2a00..96583db 100644
--- a/avro_derive/src/lib.rs
+++ b/avro_derive/src/lib.rs
@@ -32,17 +32,17 @@
 mod attributes;
 mod case;
 mod enums;
+mod tuple;
 
 use proc_macro2::{Span, TokenStream};
 use quote::quote;
 use syn::{
-    DataStruct, DeriveInput, Expr, Field, Fields, Generics, Ident, Type, 
parse_macro_input,
-    spanned::Spanned,
+    DataStruct, DeriveInput, Expr, Field, Fields, FieldsNamed, Generics, 
Ident, Type, parse_macro_input, spanned::Spanned
 };
 
 use crate::{
-    attributes::{FieldDefault, FieldOptions, NamedTypeOptions, With},
-    case::RenameRule,
+    attributes::{FieldOptions, NamedTypeOptions, With},
+    case::RenameRule, tuple::unnamed_to_record_fields,
 };
 
 #[proc_macro_derive(AvroSchema, attributes(avro, serde))]
@@ -84,7 +84,6 @@ fn derive_avro_schema(input: DeriveInput) -> 
Result<TokenStream, Vec<syn::Error>
                     let (schema_def, record_fields) = get_struct_schema_def(
                         &named_type_options,
                         data_struct,
-                        input.ident.span(),
                     )?;
                     (
                         handle_named_schemas(named_type_options.name, 
schema_def),
@@ -173,91 +172,16 @@ fn handle_named_schemas(full_schema_name: String, 
schema_def: TokenStream) -> To
 fn get_struct_schema_def(
     container_attrs: &NamedTypeOptions,
     data_struct: DataStruct,
-    ident_span: Span,
 ) -> Result<(TokenStream, TokenStream), Vec<syn::Error>> {
-    let mut record_field_exprs = vec![];
+    let mut record_field_exprs = Vec::new();
     match data_struct.fields {
         Fields::Named(a) => {
-            for field in a.named {
-                let mut name = field
-                    .ident
-                    .as_ref()
-                    .expect("Field must have a name")
-                    .to_string();
-                if let Some(raw_name) = name.strip_prefix("r#") {
-                    name = raw_name.to_string();
-                }
-                let field_attrs = FieldOptions::new(&field.attrs, 
field.span())?;
-                let doc = preserve_optional(field_attrs.doc);
-                match (field_attrs.rename, container_attrs.rename_all) {
-                    (Some(rename), _) => {
-                        name = rename;
-                    }
-                    (None, rename_all) if rename_all != RenameRule::None => {
-                        name = rename_all.apply_to_field(&name);
-                    }
-                    _ => {}
-                }
-                if field_attrs.skip {
-                    continue;
-                } else if field_attrs.flatten {
-                    // Inline the fields of the child record at runtime, as we 
don't have access to
-                    // the schema here.
-                    let get_record_fields =
-                        get_field_get_record_fields_expr(&field, 
field_attrs.with)?;
-                    record_field_exprs.push(quote! {
-                        if let Some(flattened_fields) = #get_record_fields {
-                            schema_fields.extend(flattened_fields);
-                        } else {
-                            panic!("{} does not have any fields to flatten 
to", stringify!(#field));
-                        }
-                    });
-
-                    // Don't add this field as it's been replaced by the child 
record fields
-                    continue;
-                }
-                let default_value = match field_attrs.default {
-                    FieldDefault::Disabled => quote! { None },
-                    FieldDefault::Trait => 
type_to_field_default_expr(&field.ty)?,
-                    FieldDefault::Value(default_value) => {
-                        let _: serde_json::Value = 
serde_json::from_str(&default_value[..])
-                            .map_err(|e| {
-                                vec![syn::Error::new(
-                                    field.ident.span(),
-                                    format!("Invalid avro default json: 
\n{e}"),
-                                )]
-                            })?;
-                        quote! {
-                            
Some(::serde_json::from_str(#default_value).expect(format!("Invalid JSON: 
{:?}", #default_value).as_str()))
-                        }
-                    }
-                };
-                let aliases = field_aliases(&field_attrs.alias);
-                let schema_expr = get_field_schema_expr(&field, 
field_attrs.with)?;
-                record_field_exprs.push(quote! {
-                    schema_fields.push(::apache_avro::schema::RecordField {
-                        name: #name.to_string(),
-                        doc: #doc,
-                        default: #default_value,
-                        aliases: #aliases,
-                        schema: #schema_expr,
-                        custom_attributes: ::std::collections::BTreeMap::new(),
-                    });
-                });
-            }
+            record_field_exprs.extend(named_to_record_fields(a, 
container_attrs.rename_all)?);
         }
-        Fields::Unnamed(_) => {
-            return Err(vec![syn::Error::new(
-                ident_span,
-                "AvroSchema derive does not work for tuple structs",
-            )]);
-        }
-        Fields::Unit => {
-            return Err(vec![syn::Error::new(
-                ident_span,
-                "AvroSchema derive does not work for unit structs",
-            )]);
+        Fields::Unnamed(unnamed) => {
+            record_field_exprs.extend(unnamed_to_record_fields(unnamed)?);
         }
+        Fields::Unit => {}
     }
 
     let record_doc = preserve_optional(container_attrs.doc.as_ref());
@@ -332,13 +256,36 @@ fn get_transparent_struct_schema_def(
                 )])
             }
         }
-        Fields::Unnamed(_) => Err(vec![syn::Error::new(
-            input_span,
-            "AvroSchema: derive does not work for tuple structs",
-        )]),
+        Fields::Unnamed(unnamed) => {
+            let mut found = None;
+            for field in unnamed.unnamed {
+                let attrs = FieldOptions::new(&field.attrs, field.span())?;
+                if attrs.skip {
+                    continue;
+                }
+                if found.replace((field, attrs)).is_some() {
+                    return Err(vec![syn::Error::new(
+                        input_span,
+                        "AvroSchema: #[serde(transparent)] is only allowed on 
structs with one unskipped field",
+                    )]);
+                }
+            }
+
+            if let Some((field, attrs)) = found {
+                Ok((
+                    get_field_schema_expr(&field, attrs.with.clone())?,
+                    get_field_get_record_fields_expr(&field, attrs.with)?,
+                ))
+            } else {
+                Err(vec![syn::Error::new(
+                    input_span,
+                    "AvroSchema: #[serde(transparent)] is only allowed on 
structs with one unskipped field",
+                )])
+            }
+        },
         Fields::Unit => Err(vec![syn::Error::new(
             input_span,
-            "AvroSchema: derive does not work for unit structs",
+            "AvroSchema: `#[serde(transparent)` does not work for unit 
structs",
         )]),
     }
 }
@@ -469,6 +416,62 @@ fn type_to_field_default_expr(ty: &Type) -> 
Result<TokenStream, Vec<syn::Error>>
     }
 }
 
+/// Create a vector of `RecordField`s.
+fn named_to_record_fields(named: FieldsNamed, rename_all: RenameRule) -> 
Result<Vec<TokenStream>, Vec<syn::Error>> {
+    let mut fields = Vec::with_capacity(named.named.len());
+    for field in named.named {
+        let field_attrs = FieldOptions::new(&field.attrs, field.span())?;
+        if field_attrs.skip {
+            continue;
+        } else if field_attrs.flatten {
+            // Inline the fields of the child record at runtime, as we don't 
have access to
+            // the schema here.
+            let get_record_fields = get_field_get_record_fields_expr(&field, 
field_attrs.with)?;
+            fields.push(quote! {
+                if let Some(flattened_fields) = #get_record_fields {
+                    schema_fields.extend(flattened_fields);
+                } else {
+                    panic!("{} does not have any fields to flatten to", 
stringify!(#field));
+                }
+            });
+
+            // Don't add this field as it's been replaced by the child record 
fields
+            continue;
+        }
+        let mut name = field
+            .ident
+            .as_ref()
+            .expect("Field must have a name")
+            .to_string();
+        if let Some(raw_name) = name.strip_prefix("r#") {
+            name = raw_name.to_string();
+        }
+        match (field_attrs.rename, rename_all) {
+            (Some(rename), _) => {
+                name = rename;
+            }
+            (None, rename_all) if rename_all != RenameRule::None => {
+                name = rename_all.apply_to_field(&name);
+            }
+            _ => {}
+        }
+        let default_value = 
field_attrs.default.into_tokenstream(field.ident.span(), &field.ty)?;
+        let aliases = field_aliases(&field_attrs.alias);
+        let doc = doc_into_tokenstream(field_attrs.doc);
+        let field_schema_expr = type_to_schema_expr(&field.ty)?;
+        fields.push(quote! {
+            ::apache_avro::schema::RecordField::builder()
+                .name(#name.to_string())
+                .maybe_doc(#doc)
+                .maybe_default(#default_value)
+                .aliases(#aliases)
+                .schema(#field_schema_expr)
+                .build()
+        });
+    }
+    Ok(fields)
+}
+
 /// 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);
@@ -482,6 +485,13 @@ fn preserve_optional(op: Option<impl quote::ToTokens>) -> 
TokenStream {
     }
 }
 
+fn doc_into_tokenstream(doc: Option<String>) -> TokenStream {
+    match doc {
+        Some(doc) => quote! {::std::option::Option::Some(#doc.to_string())},
+        None => quote! {::std::option::Option::None},
+    }
+}
+
 fn aliases(op: &[impl quote::ToTokens]) -> TokenStream {
     let items: Vec<TokenStream> = op
         .iter()
@@ -511,38 +521,6 @@ mod tests {
     use super::*;
     use pretty_assertions::assert_eq;
 
-    #[test]
-    fn tuple_struct_unsupported() {
-        let test_tuple_struct = quote! {
-            struct B (i32, String);
-        };
-
-        match syn::parse2::<DeriveInput>(test_tuple_struct) {
-            Ok(input) => {
-                assert!(derive_avro_schema(input).is_err())
-            }
-            Err(error) => panic!(
-                "Failed to parse as derive input when it should be able to. 
Error: {error:?}"
-            ),
-        };
-    }
-
-    #[test]
-    fn unit_struct_unsupported() {
-        let test_tuple_struct = quote! {
-            struct AbsoluteUnit;
-        };
-
-        match syn::parse2::<DeriveInput>(test_tuple_struct) {
-            Ok(input) => {
-                assert!(derive_avro_schema(input).is_err())
-            }
-            Err(error) => panic!(
-                "Failed to parse as derive input when it should be able to. 
Error: {error:?}"
-            ),
-        };
-    }
-
     #[test]
     fn struct_with_optional() {
         let struct_with_optional = quote! {
diff --git a/avro_derive/src/tuple.rs b/avro_derive/src/tuple.rs
new file mode 100644
index 0000000..8d98995
--- /dev/null
+++ b/avro_derive/src/tuple.rs
@@ -0,0 +1,59 @@
+use proc_macro2::TokenStream;
+use syn::{FieldsUnnamed, spanned::Spanned};
+use quote::quote;
+
+use crate::{FieldOptions, doc_into_tokenstream, field_aliases, 
type_to_schema_expr};
+
+/// Create a `Schema::Record` from this tuple definition.
+/// 
+/// Fields are named `field_{field_index}` and the struct will have the 
provided name.
+/// 
+/// The schema will have the attribute `org.apache.avro.rust.tuple` any any 
other specified in `extra_attributes`.
+/// All attributes will have a value of `true`.
+pub fn tuple_to_record_schema(unnamed: FieldsUnnamed, name: &str, 
extra_attributes: &[&str]) -> Result<TokenStream, Vec<syn::Error>> {
+    let fields = unnamed_to_record_fields(unnamed)?;
+
+    Ok(quote! {        
+        
::apache_avro::schema::Schema::Record(::apache_avro::schema::RecordSchema::builder()
+            
.name(::apache_avro::schema::Name::new_with_enclosing_namespace(#name, 
enclosing_namespace).expect(&format!("Unable to parse variant record name for 
schema {}", #name)[..]))
+            .fields(vec![#(#fields,)*])
+            .attributes(
+                [
+                    ("org.apache.avro.rust.tuple".to_string(), 
::serde_json::value::Value::Bool(true)),
+                    #((#extra_attributes.to_string(), 
::serde_json::value::Value::Bool(true)),)*
+                ].into()
+            )
+            .build()
+        )
+    })
+}
+
+/// Create a vector of `RecordField`s named `field_{field_index}`.
+pub fn unnamed_to_record_fields(unnamed: FieldsUnnamed) -> 
Result<Vec<TokenStream>, Vec<syn::Error>> {
+    let mut fields = Vec::with_capacity(unnamed.unnamed.len());
+    for (index, field) in unnamed.unnamed.into_iter().enumerate() {
+        let field_attrs = FieldOptions::new(&field.attrs, field.span())?;
+        if field_attrs.skip {
+            continue;
+        } else if field_attrs.flatten {
+            return Err(vec![
+                syn::Error::new(field.span(), "AvroSchema: `#[serde(flatten)]` 
is not supported on tuple fields")
+            ]);
+        }
+        let default_value = 
field_attrs.default.into_tokenstream(field.ident.span(), &field.ty)?;
+        let aliases = field_aliases(&field_attrs.alias);
+        let doc = doc_into_tokenstream(field_attrs.doc);
+        let name = field_attrs.rename.unwrap_or_else(|| 
format!("field_{index}"));
+        let field_schema_expr = type_to_schema_expr(&field.ty)?;
+        fields.push(quote! {
+            ::apache_avro::schema::RecordField::builder()
+                .name(#name.to_string())
+                .maybe_doc(#doc)
+                .maybe_default(#default_value)
+                .aliases(#aliases)
+                .schema(#field_schema_expr)
+                .build()
+        });
+    }
+    Ok(fields)
+}
diff --git 
a/avro_derive/tests/expanded/avro_3709_record_field_attributes.expanded.rs 
b/avro_derive/tests/expanded/avro_3709_record_field_attributes.expanded.rs
index e0e46b5..142b403 100644
--- a/avro_derive/tests/expanded/avro_3709_record_field_attributes.expanded.rs
+++ b/avro_derive/tests/expanded/avro_3709_record_field_attributes.expanded.rs
@@ -28,7 +28,7 @@ impl ::apache_avro::AvroSchemaComponent for A {
                 schema_fields
                     .push(::apache_avro::schema::RecordField {
                         name: "a3".to_string(),
-                        doc: ::std::option::Option::Some("a doc".into()),
+                        doc: ::std::option::Option::Some("a doc".to_string()),
                         default: Some(
                             ::serde_json::from_str("123")
                                 .expect(
@@ -110,7 +110,7 @@ impl ::apache_avro::AvroSchemaComponent for A {
         schema_fields
             .push(::apache_avro::schema::RecordField {
                 name: "a3".to_string(),
-                doc: ::std::option::Option::Some("a doc".into()),
+                doc: ::std::option::Option::Some("a doc".to_string()),
                 default: Some(
                     ::serde_json::from_str("123")
                         .expect(
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_bare_union.expanded.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_bare_union.expanded.rs
new file mode 100644
index 0000000..653186e
--- /dev/null
+++ b/avro_derive/tests/expanded/avro_rs_xxx_bare_union.expanded.rs
@@ -0,0 +1,239 @@
+use apache_avro::AvroSchema;
+#[serde(untagged)]
+enum Abc {
+    A,
+    B(bool),
+    C(#[avro(doc = "This is an int")] i32, i64),
+    D {},
+    E { is_it_true: bool },
+    F { #[avro(doc = "This is X")] x: f64, y: f32 },
+}
+#[automatically_derived]
+impl ::apache_avro::AvroSchemaComponent for Abc {
+    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(
+                "Abc",
+                enclosing_namespace,
+            )
+            .expect("Unable to parse schema name Abc");
+        if named_schemas.contains(&name) {
+            ::apache_avro::schema::Schema::Ref {
+                name,
+            }
+        } else {
+            let enclosing_namespace = name.namespace();
+            named_schemas.insert(name.clone());
+            let mut builder = ::apache_avro::schema::UnionSchema::builder();
+            builder
+                .variant(::apache_avro::schema::Schema::Null)
+                .expect("Duplicate Schema found");
+            builder
+                .variant(
+                    <bool as 
::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(
+                        named_schemas,
+                        enclosing_namespace,
+                    ),
+                )
+                .expect("Duplicate Schema found");
+            builder
+                .variant(
+                    ::apache_avro::schema::Schema::Record(
+                        ::apache_avro::schema::RecordSchema::builder()
+                            .name(
+                                
::apache_avro::schema::Name::new_with_enclosing_namespace(
+                                        "C",
+                                        enclosing_namespace,
+                                    )
+                                    .expect(
+                                        &::alloc::__export::must_use({
+                                            ::alloc::fmt::format(
+                                                format_args!(
+                                                    "Unable to parse variant 
record name for schema {0}", "C",
+                                                ),
+                                            )
+                                        })[..],
+                                    ),
+                            )
+                            .fields(
+                                
::alloc::boxed::box_assume_init_into_vec_unsafe(
+                                    ::alloc::intrinsics::write_box_via_move(
+                                        ::alloc::boxed::Box::new_uninit(),
+                                        [
+                                            
::apache_avro::schema::RecordField::builder()
+                                                .name("field_0".to_string())
+                                                .maybe_doc(
+                                                    
::std::option::Option::Some("This is an int".to_string()),
+                                                )
+                                                .maybe_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,
+                                                    ),
+                                                )
+                                                .build(),
+                                            
::apache_avro::schema::RecordField::builder()
+                                                .name("field_1".to_string())
+                                                
.maybe_doc(::std::option::Option::None)
+                                                .maybe_default(
+                                                    <i64 as 
::apache_avro::AvroSchemaComponent>::field_default(),
+                                                )
+                                                
.aliases(::std::vec::Vec::new())
+                                                .schema(
+                                                    <i64 as 
::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(
+                                                        named_schemas,
+                                                        enclosing_namespace,
+                                                    ),
+                                                )
+                                                .build(),
+                                        ],
+                                    ),
+                                ),
+                            )
+                            .attributes(
+                                [
+                                    (
+                                        
"org.apache.avro.rust.tuple".to_string(),
+                                        ::serde_json::value::Value::Bool(true),
+                                    ),
+                                ]
+                                    .into(),
+                            )
+                            .build(),
+                    ),
+                )
+                .expect("Duplicate Schema found");
+            builder
+                .variant(
+                    ::apache_avro::schema::Schema::Record(
+                        ::apache_avro::schema::RecordSchema::builder()
+                            .name(
+                                
::apache_avro::schema::Name::new_with_enclosing_namespace(
+                                        "D",
+                                        enclosing_namespace,
+                                    )
+                                    .expect(
+                                        &::alloc::__export::must_use({
+                                            ::alloc::fmt::format(
+                                                format_args!(
+                                                    "Unable to parse variant 
record name for schema {0}", "D",
+                                                ),
+                                            )
+                                        })[..],
+                                    ),
+                            )
+                            .fields(::alloc::vec::Vec::new())
+                            .build(),
+                    ),
+                )
+                .expect("Duplicate Schema found");
+            builder
+                .variant(
+                    ::apache_avro::schema::Schema::Record(
+                        ::apache_avro::schema::RecordSchema::builder()
+                            .name(
+                                
::apache_avro::schema::Name::new_with_enclosing_namespace(
+                                        "E",
+                                        enclosing_namespace,
+                                    )
+                                    .expect(
+                                        &::alloc::__export::must_use({
+                                            ::alloc::fmt::format(
+                                                format_args!(
+                                                    "Unable to parse variant 
record name for schema {0}", "E",
+                                                ),
+                                            )
+                                        })[..],
+                                    ),
+                            )
+                            .fields(
+                                
::alloc::boxed::box_assume_init_into_vec_unsafe(
+                                    ::alloc::intrinsics::write_box_via_move(
+                                        ::alloc::boxed::Box::new_uninit(),
+                                        [
+                                            
::apache_avro::schema::RecordField::builder()
+                                                .name("is_it_true".to_string())
+                                                .schema(
+                                                    <bool as 
::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(
+                                                        named_schemas,
+                                                        enclosing_namespace,
+                                                    ),
+                                                )
+                                                .build(),
+                                        ],
+                                    ),
+                                ),
+                            )
+                            .build(),
+                    ),
+                )
+                .expect("Duplicate Schema found");
+            builder
+                .variant(
+                    ::apache_avro::schema::Schema::Record(
+                        ::apache_avro::schema::RecordSchema::builder()
+                            .name(
+                                
::apache_avro::schema::Name::new_with_enclosing_namespace(
+                                        "F",
+                                        enclosing_namespace,
+                                    )
+                                    .expect(
+                                        &::alloc::__export::must_use({
+                                            ::alloc::fmt::format(
+                                                format_args!(
+                                                    "Unable to parse variant 
record name for schema {0}", "F",
+                                                ),
+                                            )
+                                        })[..],
+                                    ),
+                            )
+                            .fields(
+                                
::alloc::boxed::box_assume_init_into_vec_unsafe(
+                                    ::alloc::intrinsics::write_box_via_move(
+                                        ::alloc::boxed::Box::new_uninit(),
+                                        [
+                                            
::apache_avro::schema::RecordField::builder()
+                                                .name("x".to_string())
+                                                .schema(
+                                                    <f64 as 
::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(
+                                                        named_schemas,
+                                                        enclosing_namespace,
+                                                    ),
+                                                )
+                                                .build(),
+                                            
::apache_avro::schema::RecordField::builder()
+                                                .name("y".to_string())
+                                                .schema(
+                                                    <f32 as 
::apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(
+                                                        named_schemas,
+                                                        enclosing_namespace,
+                                                    ),
+                                                )
+                                                .build(),
+                                        ],
+                                    ),
+                                ),
+                            )
+                            .build(),
+                    ),
+                )
+                .expect("Duplicate Schema found");
+            ::apache_avro::schema::Schema::Union(builder.build())
+        }
+    }
+    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>> {
+        None
+    }
+    fn field_default() -> ::std::option::Option<::serde_json::Value> {
+        ::std::option::Option::None
+    }
+}
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_bare_union.rs
similarity index 76%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_bare_union.rs
index b23413b..34a3c51 100644
--- a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
+++ b/avro_derive/tests/expanded/avro_rs_xxx_bare_union.rs
@@ -18,17 +18,22 @@
 use apache_avro::AvroSchema;
 
 #[derive(AvroSchema)]
-struct A {
-    a: i32,
-    b: String,
+#[serde(untagged)]
+enum Abc {
+    A,
+    B(bool),
+    C(
+        #[avro(doc = "This is an int")]
+        i32, 
+        i64
+    ),
+    D {},
+    E {
+        is_it_true: bool,
+    },
+    F {
+        #[avro(doc = "This is X")]
+        x: f64,
+        y: f32,
+    }
 }
-
-#[derive(AvroSchema)]
-#[serde(transparent)]
-struct B {
-    a: A,
-}
-
-// #[derive(AvroSchema)]
-// #[serde(transparent)]
-// struct C(A);
diff --git 
a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_internally_tagged.expanded.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_internally_tagged.expanded.rs
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_internally_tagged.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_internally_tagged.rs
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
index 83b87d8..77cf011 100644
--- 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
@@ -139,15 +139,21 @@ impl ::apache_avro::AvroSchemaComponent for B {
         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)
+        <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::get_record_fields_in_ctxt(named_schemas, enclosing_namespace)
+        <A as ::apache_avro::AvroSchemaComponent>::get_record_fields_in_ctxt(
+            named_schemas,
+            enclosing_namespace,
+        )
     }
     fn field_default() -> ::std::option::Option<::serde_json::Value> {
-        A::field_default()
+        <A as ::apache_avro::AvroSchemaComponent>::field_default()
     }
 }
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
index b85a630..f391930 100644
--- a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs
+++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs
@@ -157,3 +157,29 @@ impl ::apache_avro::AvroSchemaComponent for B {
         ::std::option::Option::None
     }
 }
+#[serde(transparent)]
+struct C(A);
+#[automatically_derived]
+impl ::apache_avro::AvroSchemaComponent for C {
+    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/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
index b23413b..aa0a1bc 100644
--- a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
+++ b/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
@@ -29,6 +29,6 @@ struct B {
     a: A,
 }
 
-// #[derive(AvroSchema)]
-// #[serde(transparent)]
-// struct C(A);
+#[derive(AvroSchema)]
+#[serde(transparent)]
+struct C(A);
diff --git 
a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_tag_content.expanded.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_tag_content.expanded.rs
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_tag_content.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_tag_content.rs
diff --git 
a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_union_of_records.expanded.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.expanded.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_union_of_records.expanded.rs
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/expanded/avro_rs_xxx_union_of_records.rs
similarity index 100%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
copy to avro_derive/tests/expanded/avro_rs_xxx_union_of_records.rs
diff --git a/avro_derive/tests/expanded/mod.rs 
b/avro_derive/tests/expanded/mod.rs
index edea4cf..b21cdd8 100644
--- a/avro_derive/tests/expanded/mod.rs
+++ b/avro_derive/tests/expanded/mod.rs
@@ -23,3 +23,7 @@ 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;
+// mod avro_rs_xxx_bare_union;
+mod avro_rs_xxx_internally_tagged;
+mod avro_rs_xxx_tag_content;
+mod avro_rs_xxx_union_of_records;
diff --git a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs 
b/avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.rs
similarity index 79%
copy from avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
copy to avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.rs
index b23413b..d209315 100644
--- a/avro_derive/tests/expanded/avro_rs_xxx_serde_transparent.rs
+++ b/avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.rs
@@ -18,17 +18,24 @@
 use apache_avro::AvroSchema;
 
 #[derive(AvroSchema)]
-struct A {
-    a: i32,
-    b: String,
+#[avro(repr = "bare_union")]
+enum A {
+    A
 }
 
 #[derive(AvroSchema)]
-#[serde(transparent)]
-struct B {
-    a: A,
+#[avro(repr = "bare_union")]
+#[serde(untagged)]
+enum B {
+    A,
+    B,
 }
 
-// #[derive(AvroSchema)]
-// #[serde(transparent)]
-// struct C(A);
+#[derive(AvroSchema)]
+#[avro(repr = "bare_union")]
+#[serde(untagged)]
+enum C {
+    A(),
+}
+
+pub fn main() {}
diff --git a/avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.stderr 
b/avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.stderr
new file mode 100644
index 0000000..dbe041a
--- /dev/null
+++ b/avro_derive/tests/ui/avro_rs_xxx_bare_union_and_untagged.stderr
@@ -0,0 +1,20 @@
+error: AvroSchema: `#[avro(repr = "bare_union")]` requires `#[serde(untagged)]`
+  --> tests/ui/avro_rs_xxx_bare_union_and_untagged.rs:21:1
+   |
+21 | / #[avro(repr = "bare_union")]
+22 | | enum A {
+23 | |     A
+24 | | }
+   | |_^
+
+error: More than one variant maps to Schema::Null, this is not supported for 
bare unions
+  --> tests/ui/avro_rs_xxx_bare_union_and_untagged.rs:29:6
+   |
+29 | enum B {
+   |      ^
+
+error: AvroSchema: Empty tuple variants are not supported for bare unions
+  --> tests/ui/avro_rs_xxx_bare_union_and_untagged.rs:38:6
+   |
+38 |     A(),
+   |      ^^
diff --git a/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.stderr 
b/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.stderr
new file mode 100644
index 0000000..bad93cc
--- /dev/null
+++ b/avro_derive/tests/ui/avro_rs_xxx_serde_transparent_enum.stderr
@@ -0,0 +1,8 @@
+error: AvroSchema: `#[serde(transparent)]` is only supported on structs
+  --> tests/ui/avro_rs_xxx_serde_transparent_enum.rs:21:1
+   |
+21 | / #[serde(transparent)]
+22 | | enum D {
+23 | |     A(A)
+24 | | }
+   | |_^

Reply via email to