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


The following commit(s) were added to refs/heads/feat/enums by this push:
     new 92a8908  only some tests to update
92a8908 is described below

commit 92a8908af0da60aa3a330d4611732d453cac0813
Author: Kriskras99 <[email protected]>
AuthorDate: Wed Mar 11 22:00:53 2026 +0100

    only some tests to update
---
 avro/src/schema/mod.rs    |  70 ++++++++++-
 avro/src/serde/derive.rs  | 312 ++++++++++++++++++++++++++++++++++++++++++++++
 avro_derive/src/fields.rs | 252 ++-----------------------------------
 3 files changed, 389 insertions(+), 245 deletions(-)

diff --git a/avro/src/schema/mod.rs b/avro/src/schema/mod.rs
index b9a75f5..06f56be 100644
--- a/avro/src/schema/mod.rs
+++ b/avro/src/schema/mod.rs
@@ -49,6 +49,7 @@ use serde::{
     ser::{SerializeMap, SerializeSeq},
 };
 use serde_json::{Map, Value as JsonValue};
+use std::borrow::Cow;
 use std::fmt::Formatter;
 use std::{
     collections::{BTreeMap, HashMap, HashSet},
@@ -417,9 +418,9 @@ impl FixedSchema {
 #[derive(Debug, Clone)]
 pub struct DecimalSchema {
     /// The number of digits in the unscaled value
-    pub precision: DecimalMetadata,
+    pub precision: Precision,
     /// The number of digits to the right of the decimal point
-    pub scale: DecimalMetadata,
+    pub scale: Scale,
     /// The inner schema of the decimal (fixed or bytes)
     pub inner: InnerDecimalSchema,
 }
@@ -788,6 +789,71 @@ impl Schema {
         }
         Ok(())
     }
+
+    /// Create a name for this schema.
+    ///
+    /// The name is a valid schema name and will be unique for different
+    /// schemas.
+    ///
+    /// Requires that named schemas have unique names.
+    pub(crate) fn unique_normalized_name(&self) -> Cow<'static, str> {
+        match self {
+            Schema::Null => Cow::Borrowed("null"),
+            Schema::Boolean => Cow::Borrowed("boolean"),
+            Schema::Int => Cow::Borrowed("int"),
+            Schema::Long => Cow::Borrowed("long"),
+            Schema::Float => Cow::Borrowed("float"),
+            Schema::Double => Cow::Borrowed("double"),
+            Schema::Bytes => Cow::Borrowed("bytes"),
+            Schema::String => Cow::Borrowed("string"),
+            Schema::Array(array) => {
+                Cow::Owned(format!("array_{}", 
array.items.unique_normalized_name()))
+            }
+            Schema::Map(map) => Cow::Owned(format!("map_{}", 
map.types.unique_normalized_name())),
+            Schema::Union(union) => {
+                let mut name = format!("union_{}", union.schemas.len());
+                for schema in &union.schemas {
+                    name.push('_');
+                    name.push_str(&schema.unique_normalized_name());
+                }
+                Cow::Owned(name)
+            }
+            Schema::BigDecimal => Cow::Borrowed("big_decimal"),
+            Schema::Date => Cow::Borrowed("date"),
+            Schema::TimeMillis => Cow::Borrowed("time_millis"),
+            Schema::TimeMicros => Cow::Borrowed("time_micros"),
+            Schema::TimestampMillis => Cow::Borrowed("timestamp_millis"),
+            Schema::TimestampMicros => Cow::Borrowed("timestamp_micros"),
+            Schema::TimestampNanos => Cow::Borrowed("timestamp_nanos"),
+            Schema::LocalTimestampMillis => 
Cow::Borrowed("local_timestamp_millis"),
+            Schema::LocalTimestampMicros => 
Cow::Borrowed("local_timestamp_micros"),
+            Schema::LocalTimestampNanos => 
Cow::Borrowed("local_timestamp_nanos"),
+            Schema::Decimal(DecimalSchema {
+                inner: InnerDecimalSchema::Bytes,
+                precision,
+                scale,
+            }) => Cow::Owned(format!("decimal_bytes_{precision}_{scale}")),
+            Schema::Uuid(UuidSchema::Bytes) => Cow::Borrowed("uuid_bytes"),
+            Schema::Uuid(UuidSchema::String) => Cow::Borrowed("uuid_string"),
+            Schema::Record(RecordSchema { name, .. })
+            | Schema::Enum(EnumSchema { name, .. })
+            | Schema::Fixed(FixedSchema { name, .. })
+            | Schema::Decimal(DecimalSchema {
+                inner: InnerDecimalSchema::Fixed(FixedSchema { name, .. }),
+                ..
+            })
+            | Schema::Uuid(UuidSchema::Fixed(FixedSchema { name, .. }))
+            | Schema::Duration(FixedSchema { name, .. })
+            | Schema::Ref { name } => {
+                let name: String = name
+                    .to_string()
+                    .chars()
+                    .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
+                    .collect();
+                Cow::Owned(format!("ref_{}_{}", name.len(), name))
+            }
+        }
+    }
 }
 
 impl Serialize for Schema {
diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs
index 8ffc3de..5be4fed 100644
--- a/avro/src/serde/derive.rs
+++ b/avro/src/serde/derive.rs
@@ -19,6 +19,7 @@ use crate::Schema;
 use crate::schema::{
     FixedSchema, Name, NamespaceRef, RecordField, RecordSchema, UnionSchema, 
UuidSchema,
 };
+use serde_json::Value;
 use std::borrow::Cow;
 use std::collections::{HashMap, HashSet};
 
@@ -768,6 +769,218 @@ impl AvroSchemaComponent for i128 {
     }
 }
 
+/// Schema definition for `[T; N]`.
+///
+/// Schema is defined as follows:
+/// - 0-sized arrays: [`Schema::Null`]
+/// - 1-sized arrays: `T::get_schema_in_ctxt`
+/// - N-sized arrays: [`Schema::Record`] with a field for every index
+///
+/// If you need or want a [`Schema::Array`] use [`apache_avro::serde::array`] 
instead.
+///
+/// [`apache_avro::serde::array`]: crate::serde::array
+impl<const N: usize, T: AvroSchemaComponent> AvroSchemaComponent for [T; N] {
+    fn get_schema_in_ctxt(
+        named_schemas: &mut HashSet<Name>,
+        enclosing_namespace: NamespaceRef,
+    ) -> Schema {
+        if N == 0 {
+            Schema::Null
+        } else if N == 1 {
+            T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+        } else {
+            let t_schema = T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace);
+            let name = Name::new_with_enclosing_namespace(
+                format!("array_{N}_{}", t_schema.unique_normalized_name()),
+                enclosing_namespace,
+            )
+            .expect("Name is valid");
+            if named_schemas.contains(&name) {
+                Schema::Ref { name }
+            } else {
+                named_schemas.insert(name.clone());
+
+                let t_default = T::field_default();
+                // For named types this should now be a reference
+                let t_schema_potential_ref =
+                    T::get_schema_in_ctxt(named_schemas, enclosing_namespace);
+                let fields = std::iter::once(
+                    RecordField::builder()
+                        .name("field_0".to_string())
+                        .schema(t_schema)
+                        .maybe_default(t_default.clone())
+                        .build(),
+                )
+                .chain((1..N).map(|n| {
+                    RecordField::builder()
+                        .name(format!("field_{n}"))
+                        .schema(t_schema_potential_ref.clone())
+                        .maybe_default(t_default.clone())
+                        .build()
+                }))
+                .collect();
+
+                
Schema::Record(RecordSchema::builder().name(name).fields(fields).build())
+            }
+        }
+    }
+
+    fn get_record_fields_in_ctxt(
+        named_schemas: &mut HashSet<Name>,
+        enclosing_namespace: NamespaceRef,
+    ) -> Option<Vec<RecordField>> {
+        if N == 0 {
+            None
+        } else if N == 1 {
+            T::get_record_fields_in_ctxt(named_schemas, enclosing_namespace)
+        } else {
+            let t_schema = T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace);
+            // For named types this should now be a reference
+            let t_schema_potential_ref = T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace);
+            let t_default = T::field_default();
+            Some(
+                std::iter::once(
+                    RecordField::builder()
+                        .name("field_0".to_string())
+                        .schema(t_schema)
+                        .maybe_default(t_default.clone())
+                        .build(),
+                )
+                .chain((1..N).map(|n| {
+                    RecordField::builder()
+                        .name(format!("field_{n}"))
+                        .schema(t_schema_potential_ref.clone())
+                        .maybe_default(t_default.clone())
+                        .build()
+                }))
+                .collect(),
+            )
+        }
+    }
+
+    fn field_default() -> Option<Value> {
+        if N == 0 {
+            Some(Value::Null)
+        } else if N == 1 {
+            T::field_default()
+        } else {
+            None
+        }
+    }
+}
+
+/// Schema definition for `(T₁, T₂, …, Tₙ)`.
+///
+/// Implement for tuples of up to 16 elements.
+///
+/// Schema is defined as follows:
+/// - 1-tuple: `T::get_schema_in_ctxt`
+/// - N-tuple: [`Schema::Record`] with a field for every element
+#[cfg_attr(docsrs, doc(fake_variadic))]
+impl<T> AvroSchemaComponent for (T,)
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(
+        named_schemas: &mut HashSet<Name>,
+        enclosing_namespace: NamespaceRef,
+    ) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+
+    fn get_record_fields_in_ctxt(
+        named_schemas: &mut HashSet<Name>,
+        enclosing_namespace: NamespaceRef,
+    ) -> Option<Vec<RecordField>> {
+        T::get_record_fields_in_ctxt(named_schemas, enclosing_namespace)
+    }
+
+    fn field_default() -> Option<Value> {
+        T::field_default()
+    }
+}
+
+macro_rules! tuple_impls {
+    ($($len:expr => ($($name:ident)+))+) => {
+        $(
+            #[cfg_attr(docsrs, doc(hidden))]
+            impl<$($name),+> AvroSchemaComponent for ($($name,)+)
+            where
+                $($name: AvroSchemaComponent,)+
+            {
+                tuple_impl_body!($len => ($($name)+));
+            }
+        )+
+    };
+}
+
+macro_rules! tuple_impl_body {
+    ($len:expr => ($($name:ident)+)) => {
+        fn get_schema_in_ctxt(named_schemas: &mut HashSet<Name>, 
enclosing_namespace: NamespaceRef) -> Schema {
+            let schemas: [Schema; $len] = 
[$($name::get_schema_in_ctxt(named_schemas, enclosing_namespace), )+];
+
+            let mut name = format!("tuple_{}", $len);
+            for schema in &schemas {
+                name.push('_');
+                name.push_str(&schema.unique_normalized_name());
+            }
+
+            let name = Name::new_with_enclosing_namespace(name, 
enclosing_namespace).expect("Name is valid");
+            if named_schemas.contains(&name) {
+                Schema::Ref { name }
+            } else {
+                named_schemas.insert(name.clone());
+
+                let defaults: [Option<Value>; $len] = 
[$($name::field_default(), )+];
+
+                let fields = 
schemas.into_iter().zip(defaults.into_iter()).enumerate().map(|(n, (schema, 
default))| {
+                    RecordField::builder()
+                    .name(format!("field_{n}"))
+                    .schema(schema)
+                    .maybe_default(default)
+                    .build()
+                }).collect();
+
+                Schema::Record(RecordSchema::builder()
+                    .name(name)
+                    .fields(fields)
+                    .build()
+                )
+            }
+        }
+
+        fn get_record_fields_in_ctxt(named_schemas: &mut HashSet<Name>, 
enclosing_namespace: NamespaceRef) -> Option<Vec<RecordField>> {
+            let schemas: [Schema; $len] = 
[$($name::get_schema_in_ctxt(named_schemas, enclosing_namespace), )+];
+            let defaults: [Option<Value>; $len] = [$($name::field_default(), 
)+];
+            
Some(schemas.into_iter().zip(defaults.into_iter()).enumerate().map(|(n, 
(schema, default))| {
+                RecordField::builder()
+                .name(format!("field_{n}"))
+                .schema(schema)
+                .maybe_default(default)
+                .build()
+            }).collect())
+        }
+    };
+}
+
+tuple_impls! {
+    2 => (T0 T1)
+    3 => (T0 T1 T2)
+    4 => (T0 T1 T2 T3)
+    5 => (T0 T1 T2 T3 T4)
+    6 => (T0 T1 T2 T3 T4 T5)
+    7 => (T0 T1 T2 T3 T4 T5 T6)
+    8 => (T0 T1 T2 T3 T4 T5 T6 T7)
+    9 => (T0 T1 T2 T3 T4 T5 T6 T7 T8)
+    10 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9)
+    11 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10)
+    12 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11)
+    13 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12)
+    14 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13)
+    15 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14)
+    16 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15)
+}
+
 #[cfg(test)]
 mod tests {
     use crate::{
@@ -775,6 +988,7 @@ mod tests {
         schema::{FixedSchema, Name},
     };
     use apache_avro_test_helper::TestResult;
+    use uuid::Uuid;
 
     #[test]
     fn avro_rs_401_str() -> TestResult {
@@ -896,4 +1110,102 @@ mod tests {
     fn avro_rs_489_option_option() {
         <Option<Option<i32>>>::get_schema();
     }
+
+    #[test]
+    fn avro_rs_xxx_0_array() -> TestResult {
+        let schema = Schema::parse_str(r#""null""#)?;
+
+        assert_eq!(schema, <[String; 0]>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_1_array() -> TestResult {
+        let schema = Schema::parse_str(r#""string""#)?;
+
+        assert_eq!(schema, <[String; 1]>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_n_array() -> TestResult {
+        let schema = Schema::parse_str(
+            r#"{
+            "type": "record",
+            "name": "array_5_string",
+            "fields": [
+                { "name": "field_0", "type": "string" },
+                { "name": "field_1", "type": "string" },
+                { "name": "field_2", "type": "string" },
+                { "name": "field_3", "type": "string" },
+                { "name": "field_4", "type": "string" }
+            ]
+        }"#,
+        )?;
+
+        assert_eq!(schema, <[String; 5]>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_n_array_complex_type() -> TestResult {
+        let schema = Schema::parse_str(
+            r#"{
+            "type": "record",
+            "name": "array_2_union_2_null_ref_4_uuid",
+            "fields": [
+                { "name": "field_0", "type": ["null", {"type": "fixed", 
"logicalType": "uuid", "size": 16, "name": "uuid"}], "default": null },
+                { "name": "field_1", "type": ["null", "uuid"], "default": null 
}
+            ]
+        }"#,
+        )?;
+
+        assert_eq!(schema, <[Option<Uuid>; 2]>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_1_tuple() -> TestResult {
+        let schema = Schema::parse_str(r#""string""#)?;
+
+        assert_eq!(schema, <(String,)>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_n_tuple() -> TestResult {
+        let schema = Schema::parse_str(
+            r#"{
+            "type": "record",
+            "name": "tuple_5_string_int_long_boolean_null",
+            "fields": [
+                { "name": "field_0", "type": "string" },
+                { "name": "field_1", "type": "int" },
+                { "name": "field_2", "type": "long" },
+                { "name": "field_3", "type": "boolean" },
+                { "name": "field_4", "type": "null" }
+            ]
+        }"#,
+        )?;
+
+        assert_eq!(schema, <(String, i32, i64, bool, ())>::get_schema());
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_xxx_n_tuple_complex_type() -> TestResult {
+        let schema = Schema::parse_str(
+            r#"{
+            "type": "record",
+            "name": "tuple_2_union_2_null_ref_4_uuid_union_2_null_ref_4_uuid",
+            "fields": [
+                { "name": "field_0", "type": ["null", {"type": "fixed", 
"logicalType": "uuid", "size": 16, "name": "uuid"}], "default": null },
+                { "name": "field_1", "type": ["null", "uuid"], "default": null 
}
+            ]
+        }"#,
+        )?;
+
+        assert_eq!(schema, <(Option<Uuid>, Option<Uuid>)>::get_schema());
+        Ok(())
+    }
 }
diff --git a/avro_derive/src/fields.rs b/avro_derive/src/fields.rs
index 8e4702d..a384818 100644
--- a/avro_derive/src/fields.rs
+++ b/avro_derive/src/fields.rs
@@ -1,9 +1,9 @@
 use crate::RecordField;
 use crate::attributes::{FieldDefault, With};
 use crate::utils::{Schema, TypedTokenStream};
-use quote::{ToTokens, quote};
+use quote::quote;
 use syn::spanned::Spanned;
-use syn::{Expr, ExprLit, Field, Lit, Type, TypeArray, TypeTuple};
+use syn::{Expr, Field, Type};
 
 pub fn to_schema(field: &Field, with: With) -> 
Result<TypedTokenStream<Schema>, Vec<syn::Error>> {
     match with {
@@ -109,11 +109,11 @@ pub fn to_default(
 /// An `Expr` that resolves to an instance of `Schema`.
 fn type_to_schema_expr(ty: &Type) -> Result<TypedTokenStream<Schema>, 
Vec<syn::Error>> {
     match ty {
-        Type::Slice(_) | Type::Path(_) | Type::Reference(_) => 
Ok(TypedTokenStream::<Schema>::new(
-            quote! {<#ty as :: 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)},
-        )),
-        Type::Tuple(tuple) => tuple_to_schema(tuple),
-        Type::Array(array) => array_to_schema(array),
+        Type::Tuple(_) | Type::Array(_) | Type::Slice(_) | Type::Path(_) | 
Type::Reference(_) => {
+            Ok(TypedTokenStream::<Schema>::new(
+                quote! {<#ty as :: 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)},
+            ))
+        }
         Type::Ptr(_) => Err(vec![syn::Error::new_spanned(
             ty,
             "AvroSchema: derive does not support raw pointers",
@@ -127,155 +127,15 @@ fn type_to_schema_expr(ty: &Type) -> 
Result<TypedTokenStream<Schema>, Vec<syn::E
     }
 }
 
-/// Create a schema definition for a tuple.
-///
-/// # Mapping
-/// - `0-tuple` => `Schema::Null`,
-/// - `1-tuple` => Schema of the only element,
-/// - `n-tuple` => `Schema::Record`.
-///
-/// # `TokenStream`
-/// ## Context
-/// The token stream expects the following variables to be defined:
-/// - `named_schemas`: `&mut HashSet<Name>`
-/// - `enclosing_namespace`: `Option<&str>`
-/// ## Returns
-/// An `Expr` that resolves to an instance of `Schema`.
-fn tuple_to_schema(tuple: &TypeTuple) -> Result<TypedTokenStream<Schema>, 
Vec<syn::Error>> {
-    if tuple.elems.is_empty() {
-        Ok(TypedTokenStream::<Schema>::new(
-            quote! {::apache_avro::schema::Schema::Null},
-        ))
-    } else if tuple.elems.len() == 1 {
-        type_to_schema_expr(tuple.elems.iter().next().unwrap())
-    } else {
-        let mut fields = Vec::with_capacity(tuple.elems.len());
-
-        for (index, elem) in tuple.elems.iter().enumerate() {
-            let name = format!("field_{index}");
-            let field_schema_expr = type_to_schema_expr(elem)?;
-            fields.push(quote! {
-                ::apache_avro::schema::RecordField::builder()
-                    .name(#name.to_string())
-                    .schema(#field_schema_expr)
-                    .build()
-            });
-        }
-
-        // Try to create a unique name for this record, this is done in a best 
effort way and the
-        // name is NOT recorded in `names`.
-        // This will always start and end with a `_` as `(` and `)` are not 
valid characters
-        let tuple_as_valid_name = tuple
-            .to_token_stream()
-            .to_string()
-            .chars()
-            .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
-            .collect::<String>();
-
-        let name = format!("tuple_{}{tuple_as_valid_name}", tuple.elems.len());
-
-        Ok(TypedTokenStream::<Schema>::new(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()
-            )
-        }))
-    }
-}
-
-/// Create a schema definition for an array.
-///
-/// # Mapping
-/// - `[T; 0]` => `Schema::Null`,
-/// - `[T; 1]` => Schema of `T`,
-/// - `[T; N]` => `Schema::Record`.
-///
-/// # `TokenStream`
-/// ## Context
-/// The token stream expects the following variables to be defined:
-/// - `named_schemas`: `&mut HashSet<Name>`
-/// - `enclosing_namespace`: `Option<&str>`
-/// ## Returns
-/// An `Expr` that resolves to an instance of `Schema`.
-fn array_to_schema(array: &TypeArray) -> Result<TypedTokenStream<Schema>, 
Vec<syn::Error>> {
-    let Expr::Lit(ExprLit {
-        lit: Lit::Int(lit), ..
-    }) = &array.len
-    else {
-        return Err(vec![syn::Error::new(
-            array.span(),
-            "AvroSchema: Expected a integer literal for the array length",
-        )]);
-    };
-    // This should always work as the length always needs to fit in a usize
-    let len: usize = lit.base10_parse().map_err(|e| vec![e])?;
-
-    if len == 0 {
-        Ok(TypedTokenStream::<Schema>::new(
-            quote! {::apache_avro::schema::Schema::Null},
-        ))
-    } else if len == 1 {
-        type_to_schema_expr(&array.elem)
-    } else {
-        let t_schema_expr = type_to_schema_expr(&array.elem)?;
-        let fields = (0..len).map(|index| {
-            let name = format!("field_{index}");
-            quote! {
-                ::apache_avro::schema::RecordField::builder()
-                    .name(#name.to_string())
-                    .schema(#t_schema_expr)
-                    .build()
-            }
-        });
-
-        // Try to create a unique name for this record, this is done as best 
effort and the
-        // name is NOT recorded in `names`.
-        let array_elem_as_valid_name = array
-            .elem
-            .to_token_stream()
-            .to_string()
-            .chars()
-            .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
-            .collect::<String>();
-
-        let name = format!("array_{len}_{array_elem_as_valid_name}");
-
-        Ok(TypedTokenStream::<Schema>::new(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()
-            )
-        }))
-    }
-}
-
 fn type_to_record_fields(
     ty: &Type,
 ) -> Result<TypedTokenStream<Option<Vec<RecordField>>>, Vec<syn::Error>> {
     match ty {
-        Type::Slice(_) | Type::Path(_) | Type::Reference(_) => {
+        Type::Tuple(_) | Type::Array(_) | Type::Slice(_) | Type::Path(_) | 
Type::Reference(_) => {
             Ok(TypedTokenStream::<Option<Vec<RecordField>>>::new(
                 quote! {<#ty as :: 
apache_avro::AvroSchemaComponent>::get_record_fields_in_ctxt(named_schemas, 
enclosing_namespace)},
             ))
         }
-        Type::Array(array) => array_to_record_fields(array),
-        Type::Tuple(tuple) => tuple_to_record_fields(tuple),
         Type::Ptr(_) => Err(vec![syn::Error::new_spanned(
             ty,
             "AvroSchema: derive does not support raw pointers",
@@ -289,104 +149,11 @@ fn type_to_record_fields(
     }
 }
 
-/// Create a schema definition for a tuple.
-///
-/// # Mapping
-/// - `0-tuple` => `Schema::Null`,
-/// - `1-tuple` => Schema of the only element,
-/// - `n-tuple` => `Schema::Record`.
-///
-/// # `TokenStream`
-/// ## Context
-/// The token stream expects the following variables to be defined:
-/// - `named_schemas`: `&mut HashSet<Name>`
-/// - `enclosing_namespace`: `Option<&str>`
-/// ## Returns
-/// An `Expr` that resolves to an instance of `Schema`.
-fn tuple_to_record_fields(
-    tuple: &TypeTuple,
-) -> Result<TypedTokenStream<Option<Vec<RecordField>>>, Vec<syn::Error>> {
-    if tuple.elems.is_empty() {
-        Ok(TypedTokenStream::none())
-    } else if tuple.elems.len() == 1 {
-        type_to_record_fields(tuple.elems.iter().next().unwrap())
-    } else {
-        let mut fields = Vec::with_capacity(tuple.elems.len());
-
-        for (index, elem) in tuple.elems.iter().enumerate() {
-            let name = format!("field_{index}");
-            let field_schema_expr = type_to_schema_expr(elem)?;
-            fields.push(quote! {
-                ::apache_avro::schema::RecordField::builder()
-                    .name(#name.to_string())
-                    .schema(#field_schema_expr)
-                    .build()
-            });
-        }
-
-        Ok(TypedTokenStream::new(quote! {
-            ::std::option::Option::Some(vec![#(#fields, )*])
-        }))
-    }
-}
-/// Create a schema definition for an array.
-///
-/// # Mapping
-/// - `[T; 0]` => `Schema::Null`,
-/// - `[T; 1]` => Schema of `T`,
-/// - `[T; N]` => `Schema::Record`.
-///
-/// # `TokenStream`
-/// ## Context
-/// The token stream expects the following variables to be defined:
-/// - `named_schemas`: `&mut HashSet<Name>`
-/// - `enclosing_namespace`: `Option<&str>`
-/// ## Returns
-/// An `Expr` that resolves to an instance of `Schema`.
-fn array_to_record_fields(
-    array: &TypeArray,
-) -> Result<TypedTokenStream<Option<Vec<RecordField>>>, Vec<syn::Error>> {
-    let Expr::Lit(ExprLit {
-        lit: Lit::Int(lit), ..
-    }) = &array.len
-    else {
-        return Err(vec![syn::Error::new(
-            array.span(),
-            "AvroSchema: Expected a integer literal for the array length",
-        )]);
-    };
-    // This should always work as the length always needs to fit in a usize
-    let len: usize = lit.base10_parse().map_err(|e| vec![e])?;
-
-    if len == 0 {
-        Ok(TypedTokenStream::<Option<_>>::new(
-            quote! {::std::option::Option::None},
-        ))
-    } else if len == 1 {
-        type_to_record_fields(&array.elem)
-    } else {
-        let t_schema_expr = type_to_schema_expr(&array.elem)?;
-        let fields = (0..len).map(|index| {
-            let name = format!("field_{index}");
-            quote! {
-                ::apache_avro::schema::RecordField::builder()
-                    .name(#name.to_string())
-                    .schema(#t_schema_expr)
-                    .build()
-            }
-        });
-
-        Ok(TypedTokenStream::<Option<Vec<RecordField>>>::new(quote! {
-            ::std::option::Option::Some(vec![#(#fields, )*])
-        }))
-    }
-}
-
 fn type_to_field_default(
     ty: &Type,
 ) -> Result<TypedTokenStream<Option<serde_json::Value>>, Vec<syn::Error>> {
     match ty {
-        Type::Slice(_) | Type::Path(_) | Type::Reference(_) => {
+        Type::Tuple(_) | Type::Array(_) | Type::Slice(_) | Type::Path(_) | 
Type::Reference(_) => {
             Ok(TypedTokenStream::<Option<serde_json::Value>>::new(
                 quote! {<#ty as :: 
apache_avro::AvroSchemaComponent>::field_default()},
             ))
@@ -395,7 +162,6 @@ fn type_to_field_default(
             ty,
             "AvroSchema: derive does not support raw pointers",
         )]),
-        Type::Tuple(_) | Type::Array(_) => Ok(TypedTokenStream::none()),
         _ => Err(vec![syn::Error::new_spanned(
             ty,
             format!(

Reply via email to