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

mgrigorov pushed a commit to branch 
363-make-AvroSchemaComponent-always-available
in repository https://gitbox.apache.org/repos/asf/avro-rs.git

commit f4636168f183115ce2c0d0cd6d6d931d42a6a0a4
Author: Martin Tzvetanov Grigorov <[email protected]>
AuthorDate: Thu Jan 8 06:02:27 2026 +0200

    feat!:Make AvroSchemaComponent available without `derive` feature
    
    Fixes #363
    
    Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
---
 avro/src/lib.rs             |   2 +-
 avro/src/schema.rs          | 105 ++++++++++++++++++++++----------------------
 avro_derive/src/lib.rs      |  16 +++----
 avro_derive/tests/derive.rs |   2 +-
 4 files changed, 62 insertions(+), 63 deletions(-)

diff --git a/avro/src/lib.rs b/avro/src/lib.rs
index 5c744ff..bfeb6bf 100644
--- a/avro/src/lib.rs
+++ b/avro/src/lib.rs
@@ -984,7 +984,7 @@ pub use reader::{
     GenericSingleObjectReader, Reader, SpecificSingleObjectReader, 
from_avro_datum,
     from_avro_datum_reader_schemata, from_avro_datum_schemata, read_marker,
 };
-pub use schema::{AvroSchema, Schema};
+pub use schema::{AvroSchema, AvroSchemaComponent, Schema};
 pub use serde::{de::from_value, ser::to_value};
 pub use uuid::Uuid;
 pub use writer::{
diff --git a/avro/src/schema.rs b/avro/src/schema.rs
index 9d988c8..be728f3 100644
--- a/avro/src/schema.rs
+++ b/avro/src/schema.rs
@@ -2574,64 +2574,63 @@ 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.
+///
+/// # 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(names, 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;
+}
+
 #[cfg(feature = "derive")]
 pub mod derive {
     use super::*;
     use std::borrow::Cow;
 
-    /// 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.
-    ///
-    /// # 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(names, 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,
diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs
index 8723593..c3587ed 100644
--- a/avro_derive/src/lib.rs
+++ b/avro_derive/src/lib.rs
@@ -84,7 +84,7 @@ fn derive_avro_schema(input: &mut DeriveInput) -> 
Result<TokenStream, Vec<syn::E
     let (impl_generics, ty_generics, where_clause) = 
input.generics.split_for_impl();
     Ok(quote! {
         #[automatically_derived]
-        impl #impl_generics apache_avro::schema::derive::AvroSchemaComponent 
for #ident #ty_generics #where_clause {
+        impl #impl_generics apache_avro::AvroSchemaComponent for #ident 
#ty_generics #where_clause {
             fn get_schema_in_ctxt(named_schemas: &mut 
std::collections::HashMap<apache_avro::schema::Name, 
apache_avro::schema::Schema>, enclosing_namespace: &Option<String>) -> 
apache_avro::schema::Schema {
                 let name =  
apache_avro::schema::Name::new(#full_schema_name).expect(&format!("Unable to 
parse schema name {}", 
#full_schema_name)[..]).fully_qualified_name(enclosing_namespace);
                 let enclosing_namespace = &name.namespace;
@@ -338,10 +338,10 @@ fn is_default_attr(attr: &Attribute) -> bool {
 }
 
 /// Generates the schema def expression for fully qualified type paths using 
the associated function
-/// - `A -> <A as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt()`
-/// - `A<T> -> <A<T> as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt()`
+/// - `A -> <A as apache_avro::AvroSchemaComponent>::get_schema_in_ctxt()`
+/// - `A<T> -> <A<T> as 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt()`
 fn type_path_schema_expr(p: &TypePath) -> TokenStream {
-    quote! {<#p as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas,
 enclosing_namespace)}
+    quote! {<#p as 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)}
 }
 
 /// Stolen from serde
@@ -496,7 +496,7 @@ mod tests {
                 assert!(derived.is_ok());
                 assert_eq!(derived.unwrap().to_string(), quote! {
                     #[automatically_derived]
-                    impl apache_avro::schema::derive::AvroSchemaComponent for 
Basic {
+                    impl apache_avro::AvroSchemaComponent for Basic {
                         fn get_schema_in_ctxt(
                             named_schemas: &mut std::collections::HashMap<
                                 apache_avro::schema::Name,
@@ -640,9 +640,9 @@ mod tests {
 
     #[test]
     fn test_trait_cast() {
-        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{i32}).unwrap()).to_string(),
 quote!{<i32 as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas,
 enclosing_namespace)}.to_string());
-        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{Vec<T>}).unwrap()).to_string(),
 quote!{<Vec<T> as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas,
 enclosing_namespace)}.to_string());
-        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{AnyType}).unwrap()).to_string(),
 quote!{<AnyType as 
apache_avro::schema::derive::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas,
 enclosing_namespace)}.to_string());
+        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{i32}).unwrap()).to_string(),
 quote!{<i32 as 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)}.to_string());
+        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{Vec<T>}).unwrap()).to_string(),
 quote!{<Vec<T> as 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)}.to_string());
+        
assert_eq!(type_path_schema_expr(&syn::parse2::<TypePath>(quote!{AnyType}).unwrap()).to_string(),
 quote!{<AnyType as 
apache_avro::AvroSchemaComponent>::get_schema_in_ctxt(named_schemas, 
enclosing_namespace)}.to_string());
     }
 
     #[test]
diff --git a/avro_derive/tests/derive.rs b/avro_derive/tests/derive.rs
index 72c6db0..cf3be7e 100644
--- a/avro_derive/tests/derive.rs
+++ b/avro_derive/tests/derive.rs
@@ -17,7 +17,7 @@
 
 use apache_avro::{
     Reader, Schema, Writer, from_value,
-    schema::{AvroSchema, derive::AvroSchemaComponent},
+    schema::{AvroSchema, AvroSchemaComponent},
 };
 use apache_avro_derive::*;
 use proptest::prelude::*;

Reply via email to