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

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

commit 75ca979af6b84d48e406219370b9256593e3e6b9
Author: Kriskras99 <[email protected]>
AuthorDate: Sun Jan 18 11:49:47 2026 +0100

    fix!: Move `AvroSchema` and `AvroSchemaComponent` to the `serde` module
---
 .../test_interop_single_object_encoding.rs         |   2 +-
 avro/src/lib.rs                                    |   4 +-
 avro/src/reader.rs                                 |   4 +-
 avro/src/schema/mod.rs                             | 314 +-------------------
 avro/src/serde/derive.rs                           | 322 +++++++++++++++++++++
 avro/src/serde/mod.rs                              |   3 +
 avro/src/writer.rs                                 |   4 +-
 avro_derive/tests/derive.rs                        |   5 +-
 8 files changed, 335 insertions(+), 323 deletions(-)

diff --git a/avro/examples/test_interop_single_object_encoding.rs 
b/avro/examples/test_interop_single_object_encoding.rs
index 61b1e6f..8a8b419 100644
--- a/avro/examples/test_interop_single_object_encoding.rs
+++ b/avro/examples/test_interop_single_object_encoding.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use apache_avro::{schema::AvroSchema, types::Value};
+use apache_avro::{AvroSchema, types::Value};
 use std::error::Error;
 
 struct InteropMessage;
diff --git a/avro/src/lib.rs b/avro/src/lib.rs
index 2d144ea..ac6d0bf 100644
--- a/avro/src/lib.rs
+++ b/avro/src/lib.rs
@@ -974,8 +974,8 @@ pub use reader::{
     GenericSingleObjectReader, Reader, SpecificSingleObjectReader, 
from_avro_datum,
     from_avro_datum_reader_schemata, from_avro_datum_schemata, read_marker,
 };
-pub use schema::{AvroSchema, AvroSchemaComponent, Schema};
-pub use serde::{de::from_value, ser::to_value};
+pub use schema::Schema;
+pub use serde::{AvroSchema, AvroSchemaComponent, de::from_value, 
ser::to_value};
 pub use uuid::Uuid;
 pub use writer::{
     GenericSingleObjectWriter, SpecificSingleObjectWriter, Writer, 
WriterBuilder, to_avro_datum,
diff --git a/avro/src/reader.rs b/avro/src/reader.rs
index 23af5db..d578a5f 100644
--- a/avro/src/reader.rs
+++ b/avro/src/reader.rs
@@ -17,13 +17,13 @@
 
 //! Logic handling reading from Avro format at user level.
 use crate::{
-    AvroResult, Codec, Error,
+    AvroResult, AvroSchema, Codec, Error,
     decode::{decode, decode_internal},
     error::Details,
     from_value,
     headers::{HeaderBuilder, RabinFingerprintHeader},
     schema::{
-        AvroSchema, Names, ResolvedOwnedSchema, ResolvedSchema, Schema, 
resolve_names,
+        Names, ResolvedOwnedSchema, ResolvedSchema, Schema, resolve_names,
         resolve_names_with_schemata,
     },
     types::Value,
diff --git a/avro/src/schema/mod.rs b/avro/src/schema/mod.rs
index 110d1d8..8ddd6f3 100644
--- a/avro/src/schema/mod.rs
+++ b/avro/src/schema/mod.rs
@@ -34,7 +34,7 @@ use serde::{
 };
 use serde_json::{Map, Value};
 use std::{
-    borrow::{Borrow, Cow},
+    borrow::Borrow,
     collections::{BTreeMap, HashMap, HashSet},
     fmt,
     fmt::Debug,
@@ -2583,268 +2583,6 @@ fn field_ordering_position(field: &str) -> 
Option<usize> {
         .map(|pos| pos + 1)
 }
 
-/// Trait for types that serve as an Avro data model. Derive implementation 
available
-/// through `derive` feature. Do not implement directly!
-/// Implement [`AvroSchemaComponent`] to get this trait
-/// through a blanket implementation.
-///
-/// Note: This trait is **not** implemented for `char` and `u64`. `char` is a 
32-bit value
-/// that does not have a logical mapping to an Avro schema. `u64` is too large 
to fit in a
-/// Avro `long`.
-pub trait AvroSchema {
-    fn get_schema() -> Schema;
-}
-
-/// Trait for types that serve as fully defined components inside an Avro data 
model. Derive
-/// implementation available through `derive` feature. This is what is 
implemented by
-/// the `derive(AvroSchema)` macro.
-///
-/// Note: This trait is **not** implemented for `char` and `u64`. `char` is a 
32-bit value
-/// that does not have a logical mapping to an Avro schema. `u64` is too large 
to fit in a
-/// Avro `long`.
-///
-/// # Implementation guide
-///
-/// ### Simple implementation
-/// To construct a non named simple schema, it is possible to ignore the input 
argument making the
-/// general form implementation look like
-/// ```ignore
-/// impl AvroSchemaComponent for AType {
-///     fn get_schema_in_ctxt(_: &mut Names, _: &Namespace) -> Schema {
-///        Schema::?
-///    }
-///}
-/// ```
-///
-/// ### Passthrough implementation
-///
-/// To construct a schema for a Type that acts as in "inner" type, such as for 
smart pointers, simply
-/// pass through the arguments to the inner type
-/// ```ignore
-/// impl AvroSchemaComponent for PassthroughType {
-///     fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-///        InnerType::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-///    }
-///}
-/// ```
-///
-/// ### Complex implementation
-///
-/// To implement this for Named schema there is a general form needed to avoid 
creating invalid
-/// schemas or infinite loops.
-/// ```ignore
-/// impl AvroSchemaComponent for ComplexType {
-///     fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-///         // Create the fully qualified name for your type given the 
enclosing namespace
-///         let name =  apache_avro::schema::Name::new("MyName")
-///             .expect("Unable to parse schema name")
-///             .fully_qualified_name(enclosing_namespace);
-///         let enclosing_namespace = &name.namespace;
-///         // Check, if your name is already defined, and if so, return a ref 
to that name
-///         if named_schemas.contains_key(&name) {
-///             apache_avro::schema::Schema::Ref{name: name.clone()}
-///         } else {
-///             named_schemas.insert(name.clone(), 
apache_avro::schema::Schema::Ref{name: name.clone()});
-///             // YOUR SCHEMA DEFINITION HERE with the name equivalent to 
"MyName".
-///             // For non-simple sub types delegate to their implementation 
of AvroSchemaComponent
-///         }
-///    }
-///}
-/// ```
-pub trait AvroSchemaComponent {
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema;
-}
-
-impl<T> AvroSchema for T
-where
-    T: AvroSchemaComponent + ?Sized,
-{
-    fn get_schema() -> Schema {
-        T::get_schema_in_ctxt(&mut HashMap::default(), &None)
-    }
-}
-
-macro_rules! impl_schema (
-    ($type:ty, $variant_constructor:expr) => (
-        impl AvroSchemaComponent for $type {
-            fn get_schema_in_ctxt(_: &mut Names, _: &Namespace) -> Schema {
-                $variant_constructor
-            }
-        }
-    );
-);
-
-impl_schema!(bool, Schema::Boolean);
-impl_schema!(i8, Schema::Int);
-impl_schema!(i16, Schema::Int);
-impl_schema!(i32, Schema::Int);
-impl_schema!(i64, Schema::Long);
-impl_schema!(u8, Schema::Int);
-impl_schema!(u16, Schema::Int);
-impl_schema!(u32, Schema::Long);
-impl_schema!(f32, Schema::Float);
-impl_schema!(f64, Schema::Double);
-impl_schema!(String, Schema::String);
-impl_schema!(str, Schema::String);
-
-impl<T> AvroSchemaComponent for &T
-where
-    T: AvroSchemaComponent + ?Sized,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-    }
-}
-
-impl<T> AvroSchemaComponent for &mut T
-where
-    T: AvroSchemaComponent + ?Sized,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-    }
-}
-
-impl<T> AvroSchemaComponent for [T]
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
-    }
-}
-
-impl<const N: usize, T> AvroSchemaComponent for [T; N]
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
-    }
-}
-
-impl<T> AvroSchemaComponent for Vec<T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
-    }
-}
-
-impl<T> AvroSchemaComponent for Option<T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        let variants = vec![
-            Schema::Null,
-            T::get_schema_in_ctxt(named_schemas, enclosing_namespace),
-        ];
-
-        Schema::Union(
-            UnionSchema::new(variants).expect("Option<T> must produce a valid 
(non-nested) union"),
-        )
-    }
-}
-
-impl<T> AvroSchemaComponent for Map<String, T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        Schema::map(T::get_schema_in_ctxt(named_schemas, enclosing_namespace))
-    }
-}
-
-impl<T> AvroSchemaComponent for HashMap<String, T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        Schema::map(T::get_schema_in_ctxt(named_schemas, enclosing_namespace))
-    }
-}
-
-impl<T> AvroSchemaComponent for Box<T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-    }
-}
-
-impl<T> AvroSchemaComponent for std::sync::Mutex<T>
-where
-    T: AvroSchemaComponent,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-    }
-}
-
-impl<T> AvroSchemaComponent for Cow<'_, T>
-where
-    T: AvroSchemaComponent + Clone,
-{
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
-    }
-}
-
-impl AvroSchemaComponent for core::time::Duration {
-    /// The schema is [`Schema::Duration`] with the name `duration`.
-    ///
-    /// This is a lossy conversion as this Avro type does not store the amount 
of nanoseconds.
-    #[expect(clippy::map_entry, reason = "We don't use the value from the 
map")]
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        let name = Name::new("duration")
-            .expect("Name is valid")
-            .fully_qualified_name(enclosing_namespace);
-        if named_schemas.contains_key(&name) {
-            Schema::Ref { name }
-        } else {
-            let schema = Schema::Duration(FixedSchema {
-                name: name.clone(),
-                aliases: None,
-                doc: None,
-                size: 12,
-                default: None,
-                attributes: Default::default(),
-            });
-            named_schemas.insert(name, schema.clone());
-            schema
-        }
-    }
-}
-
-impl AvroSchemaComponent for uuid::Uuid {
-    /// The schema is [`Schema::Uuid`] with the name `uuid`.
-    ///
-    /// The underlying schema is [`Schema::Fixed`] with a size of 16.
-    #[expect(clippy::map_entry, reason = "We don't use the value from the 
map")]
-    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
-        let name = Name::new("uuid")
-            .expect("Name is valid")
-            .fully_qualified_name(enclosing_namespace);
-        if named_schemas.contains_key(&name) {
-            Schema::Ref { name }
-        } else {
-            let schema = Schema::Uuid(UuidSchema::Fixed(FixedSchema {
-                name: name.clone(),
-                aliases: None,
-                doc: None,
-                size: 16,
-                default: None,
-                attributes: Default::default(),
-            }));
-            named_schemas.insert(name, schema.clone());
-            schema
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -7686,54 +7424,4 @@ mod tests {
 
         Ok(())
     }
-
-    #[test]
-    fn avro_rs_401_str() -> TestResult {
-        let schema = str::get_schema();
-        assert_eq!(schema, Schema::String);
-
-        Ok(())
-    }
-
-    #[test]
-    fn avro_rs_401_references() -> TestResult {
-        let schema_ref = <&str>::get_schema();
-        let schema_ref_mut = <&mut str>::get_schema();
-
-        assert_eq!(schema_ref, Schema::String);
-        assert_eq!(schema_ref_mut, Schema::String);
-
-        Ok(())
-    }
-
-    #[test]
-    fn avro_rs_401_slice() -> TestResult {
-        let schema = <[u8]>::get_schema();
-        assert_eq!(schema, Schema::array(Schema::Int));
-
-        Ok(())
-    }
-
-    #[test]
-    fn avro_rs_401_array() -> TestResult {
-        let schema = <[u8; 55]>::get_schema();
-        assert_eq!(schema, Schema::array(Schema::Int));
-
-        Ok(())
-    }
-
-    #[test]
-    fn avro_rs_401_option_ref_slice_array() -> TestResult {
-        let schema = <Option<&[[u8; 55]]>>::get_schema();
-        assert_eq!(
-            schema,
-            Schema::union(vec![
-                Schema::Null,
-                Schema::array(Schema::array(Schema::Int))
-            ])
-            .unwrap()
-        );
-
-        Ok(())
-    }
 }
diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs
new file mode 100644
index 0000000..0499897
--- /dev/null
+++ b/avro/src/serde/derive.rs
@@ -0,0 +1,322 @@
+use std::borrow::Cow;
+use std::collections::HashMap;
+use serde_json::Map;
+use crate::Schema;
+use crate::schema::{FixedSchema, Name, Names, Namespace, UnionSchema, 
UuidSchema};
+
+/// Trait for types that serve as an Avro data model. Derive implementation 
available
+/// through `derive` feature. Do not implement directly!
+/// Implement [`AvroSchemaComponent`] to get this trait
+/// through a blanket implementation.
+///
+/// Note: This trait is **not** implemented for `char` and `u64`. `char` is a 
32-bit value
+/// that does not have a logical mapping to an Avro schema. `u64` is too large 
to fit in a
+/// Avro `long`.
+pub trait AvroSchema {
+    fn get_schema() -> Schema;
+}
+
+/// Trait for types that serve as fully defined components inside an Avro data 
model. Derive
+/// implementation available through `derive` feature. This is what is 
implemented by
+/// the `derive(AvroSchema)` macro.
+///
+/// Note: This trait is **not** implemented for `char` and `u64`. `char` is a 
32-bit value
+/// that does not have a logical mapping to an Avro schema. `u64` is too large 
to fit in a
+/// Avro `long`.
+///
+/// # Implementation guide
+///
+/// ### Simple implementation
+/// To construct a non named simple schema, it is possible to ignore the input 
argument making the
+/// general form implementation look like
+/// ```ignore
+/// impl AvroSchemaComponent for AType {
+///     fn get_schema_in_ctxt(_: &mut Names, _: &Namespace) -> Schema {
+///        Schema::?
+///    }
+///}
+/// ```
+///
+/// ### Passthrough implementation
+///
+/// To construct a schema for a Type that acts as in "inner" type, such as for 
smart pointers, simply
+/// pass through the arguments to the inner type
+/// ```ignore
+/// impl AvroSchemaComponent for PassthroughType {
+///     fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+///        InnerType::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+///    }
+///}
+/// ```
+///
+/// ### Complex implementation
+///
+/// To implement this for Named schema there is a general form needed to avoid 
creating invalid
+/// schemas or infinite loops.
+/// ```ignore
+/// impl AvroSchemaComponent for ComplexType {
+///     fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+///         // Create the fully qualified name for your type given the 
enclosing namespace
+///         let name =  apache_avro::schema::Name::new("MyName")
+///             .expect("Unable to parse schema name")
+///             .fully_qualified_name(enclosing_namespace);
+///         let enclosing_namespace = &name.namespace;
+///         // Check, if your name is already defined, and if so, return a ref 
to that name
+///         if named_schemas.contains_key(&name) {
+///             apache_avro::schema::Schema::Ref{name: name.clone()}
+///         } else {
+///             named_schemas.insert(name.clone(), 
apache_avro::schema::Schema::Ref{name: name.clone()});
+///             // YOUR SCHEMA DEFINITION HERE with the name equivalent to 
"MyName".
+///             // For non-simple sub types delegate to their implementation 
of AvroSchemaComponent
+///         }
+///    }
+///}
+/// ```
+pub trait AvroSchemaComponent {
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema;
+}
+
+impl<T> AvroSchema for T
+where
+    T: AvroSchemaComponent + ?Sized,
+{
+    fn get_schema() -> Schema {
+        T::get_schema_in_ctxt(&mut HashMap::default(), &None)
+    }
+}
+
+macro_rules! impl_schema (
+    ($type:ty, $variant_constructor:expr) => (
+        impl AvroSchemaComponent for $type {
+            fn get_schema_in_ctxt(_: &mut Names, _: &Namespace) -> Schema {
+                $variant_constructor
+            }
+        }
+    );
+);
+
+impl_schema!(bool, Schema::Boolean);
+impl_schema!(i8, Schema::Int);
+impl_schema!(i16, Schema::Int);
+impl_schema!(i32, Schema::Int);
+impl_schema!(i64, Schema::Long);
+impl_schema!(u8, Schema::Int);
+impl_schema!(u16, Schema::Int);
+impl_schema!(u32, Schema::Long);
+impl_schema!(f32, Schema::Float);
+impl_schema!(f64, Schema::Double);
+impl_schema!(String, Schema::String);
+impl_schema!(str, Schema::String);
+
+impl<T> AvroSchemaComponent for &T
+where
+    T: AvroSchemaComponent + ?Sized,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+}
+
+impl<T> AvroSchemaComponent for &mut T
+where
+    T: AvroSchemaComponent + ?Sized,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+}
+
+impl<T> AvroSchemaComponent for [T]
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
+    }
+}
+
+impl<const N: usize, T> AvroSchemaComponent for [T; N]
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
+    }
+}
+
+impl<T> AvroSchemaComponent for Vec<T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        Schema::array(T::get_schema_in_ctxt(named_schemas, 
enclosing_namespace))
+    }
+}
+
+impl<T> AvroSchemaComponent for Option<T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        let variants = vec![
+            Schema::Null,
+            T::get_schema_in_ctxt(named_schemas, enclosing_namespace),
+        ];
+
+        Schema::Union(
+            UnionSchema::new(variants).expect("Option<T> must produce a valid 
(non-nested) union"),
+        )
+    }
+}
+
+impl<T> AvroSchemaComponent for Map<String, T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        Schema::map(T::get_schema_in_ctxt(named_schemas, enclosing_namespace))
+    }
+}
+
+impl<T> AvroSchemaComponent for HashMap<String, T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        Schema::map(T::get_schema_in_ctxt(named_schemas, enclosing_namespace))
+    }
+}
+
+impl<T> AvroSchemaComponent for Box<T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+}
+
+impl<T> AvroSchemaComponent for std::sync::Mutex<T>
+where
+    T: AvroSchemaComponent,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+}
+
+impl<T> AvroSchemaComponent for Cow<'_, T>
+where
+    T: AvroSchemaComponent + Clone,
+{
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        T::get_schema_in_ctxt(named_schemas, enclosing_namespace)
+    }
+}
+
+impl AvroSchemaComponent for core::time::Duration {
+    /// The schema is [`Schema::Duration`] with the name `duration`.
+    ///
+    /// This is a lossy conversion as this Avro type does not store the amount 
of nanoseconds.
+    #[expect(clippy::map_entry, reason = "We don't use the value from the 
map")]
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        let name = Name::new("duration")
+            .expect("Name is valid")
+            .fully_qualified_name(enclosing_namespace);
+        if named_schemas.contains_key(&name) {
+            Schema::Ref { name }
+        } else {
+            let schema = Schema::Duration(FixedSchema {
+                name: name.clone(),
+                aliases: None,
+                doc: None,
+                size: 12,
+                default: None,
+                attributes: Default::default(),
+            });
+            named_schemas.insert(name, schema.clone());
+            schema
+        }
+    }
+}
+
+impl AvroSchemaComponent for uuid::Uuid {
+    /// The schema is [`Schema::Uuid`] with the name `uuid`.
+    ///
+    /// The underlying schema is [`Schema::Fixed`] with a size of 16.
+    #[expect(clippy::map_entry, reason = "We don't use the value from the 
map")]
+    fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace) -> Schema {
+        let name = Name::new("uuid")
+            .expect("Name is valid")
+            .fully_qualified_name(enclosing_namespace);
+        if named_schemas.contains_key(&name) {
+            Schema::Ref { name }
+        } else {
+            let schema = Schema::Uuid(UuidSchema::Fixed(FixedSchema {
+                name: name.clone(),
+                aliases: None,
+                doc: None,
+                size: 16,
+                default: None,
+                attributes: Default::default(),
+            }));
+            named_schemas.insert(name, schema.clone());
+            schema
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use apache_avro_test_helper::TestResult;
+
+    #[test]
+    fn avro_rs_401_str() -> TestResult {
+        let schema = str::get_schema();
+        assert_eq!(schema, Schema::String);
+
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_401_references() -> TestResult {
+        let schema_ref = <&str>::get_schema();
+        let schema_ref_mut = <&mut str>::get_schema();
+
+        assert_eq!(schema_ref, Schema::String);
+        assert_eq!(schema_ref_mut, Schema::String);
+
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_401_slice() -> TestResult {
+        let schema = <[u8]>::get_schema();
+        assert_eq!(schema, Schema::array(Schema::Int));
+
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_401_array() -> TestResult {
+        let schema = <[u8; 55]>::get_schema();
+        assert_eq!(schema, Schema::array(Schema::Int));
+
+        Ok(())
+    }
+
+    #[test]
+    fn avro_rs_401_option_ref_slice_array() -> TestResult {
+        let schema = <Option<&[[u8; 55]]>>::get_schema();
+        assert_eq!(
+            schema,
+            Schema::union(vec![
+                Schema::Null,
+                Schema::array(Schema::array(Schema::Int))
+            ])?
+        );
+
+        Ok(())
+    }
+}
\ No newline at end of file
diff --git a/avro/src/serde/mod.rs b/avro/src/serde/mod.rs
index 3480a14..ef99a09 100644
--- a/avro/src/serde/mod.rs
+++ b/avro/src/serde/mod.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+mod derive;
 mod util;
 mod with;
 
@@ -22,5 +23,7 @@ pub mod de;
 pub mod ser;
 pub mod ser_schema;
 
+#[doc(inline)]
+pub use derive::{AvroSchema, AvroSchemaComponent};
 #[doc(inline)]
 pub use with::{bytes, bytes_opt, fixed, fixed_opt, slice, slice_opt};
diff --git a/avro/src/writer.rs b/avro/src/writer.rs
index 1c375d9..b9691a7 100644
--- a/avro/src/writer.rs
+++ b/avro/src/writer.rs
@@ -17,11 +17,11 @@
 
 //! Logic handling writing in Avro format at user level.
 use crate::{
-    AvroResult, Codec, Error,
+    AvroResult, AvroSchema, Codec, Error,
     encode::{encode, encode_internal, encode_to_vec},
     error::Details,
     headers::{HeaderBuilder, RabinFingerprintHeader},
-    schema::{AvroSchema, Name, ResolvedOwnedSchema, ResolvedSchema, Schema},
+    schema::{Name, ResolvedOwnedSchema, ResolvedSchema, Schema},
     serde::ser_schema::SchemaAwareWriteSerializer,
     types::Value,
 };
diff --git a/avro_derive/tests/derive.rs b/avro_derive/tests/derive.rs
index a1e01ef..802e752 100644
--- a/avro_derive/tests/derive.rs
+++ b/avro_derive/tests/derive.rs
@@ -16,13 +16,12 @@
 // under the License.
 
 use apache_avro::{
-    Reader, Schema, Writer, from_value,
+    AvroSchema, AvroSchemaComponent, Reader, Schema, Writer, from_value,
     schema::{
-        Alias, AvroSchema, AvroSchemaComponent, EnumSchema, FixedSchema, Name, 
Names, Namespace,
+        Alias, EnumSchema, FixedSchema, Name, Names, Namespace,
         RecordSchema,
     },
 };
-use apache_avro_derive::*;
 use proptest::prelude::*;
 use serde::{Deserialize, Serialize, de::DeserializeOwned};
 use std::{borrow::Cow, collections::HashMap, sync::Mutex};

Reply via email to