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

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

commit 57867cc5ac49e80189efe78596008a520d248684
Author: Kriskras99 <[email protected]>
AuthorDate: Tue Jan 13 22:21:18 2026 +0100

    fix(derive): do not match type by name
---
 avro/src/schema.rs          |  1 +
 avro_derive/src/lib.rs      | 37 ++++++-------------------------------
 avro_derive/tests/derive.rs | 28 ++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/avro/src/schema.rs b/avro/src/schema.rs
index 809606a..204a3af 100644
--- a/avro/src/schema.rs
+++ b/avro/src/schema.rs
@@ -2657,6 +2657,7 @@ 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_schema!(uuid::Uuid, Schema::Uuid(UuidSchema::String));
 
 impl<T> AvroSchemaComponent for Vec<T>
diff --git a/avro_derive/src/lib.rs b/avro_derive/src/lib.rs
index c3587ed..aea8ea5 100644
--- a/avro_derive/src/lib.rs
+++ b/avro_derive/src/lib.rs
@@ -267,34 +267,9 @@ fn get_data_enum_schema_def(
 /// Takes in the Tokens of a type and returns the tokens of an expression with 
return type `Schema`
 fn type_to_schema_expr(ty: &Type) -> Result<TokenStream, Vec<syn::Error>> {
     if let Type::Path(p) = ty {
-        let type_string = p.path.segments.last().unwrap().ident.to_string();
-
-        let schema = match &type_string[..] {
-            "bool" => quote! {apache_avro::schema::Schema::Boolean},
-            "i8" | "i16" | "i32" | "u8" | "u16" => quote! 
{apache_avro::schema::Schema::Int},
-            "u32" | "i64" => quote! {apache_avro::schema::Schema::Long},
-            "f32" => quote! {apache_avro::schema::Schema::Float},
-            "f64" => quote! {apache_avro::schema::Schema::Double},
-            "String" | "str" => quote! {apache_avro::schema::Schema::String},
-            "char" => {
-                return Err(vec![syn::Error::new_spanned(
-                    ty,
-                    "AvroSchema: Cannot guarantee successful deserialization 
of this type",
-                )]);
-            }
-            "u64" => {
-                return Err(vec![syn::Error::new_spanned(
-                    ty,
-                    "Cannot guarantee successful serialization of this type 
due to overflow concerns",
-                )]);
-            } // Can't guarantee serialization type
-            _ => {
-                // Fails when the type does not implement AvroSchemaComponent 
directly
-                // TODO check and error report with something like 
https://docs.rs/quote/1.0.15/quote/macro.quote_spanned.html#example
-                type_path_schema_expr(p)
-            }
-        };
-        Ok(schema)
+        // If the type does not implement AvroSchemaComponent this will cause 
a compile error
+        // indicating that
+        Ok(type_path_schema_expr(p))
     } else if let Type::Array(ta) = ty {
         let inner_schema_expr = type_to_schema_expr(&ta.elem)?;
         Ok(quote! {apache_avro::schema::Schema::array(#inner_schema_expr)})
@@ -658,7 +633,7 @@ mod tests {
         match syn::parse2::<DeriveInput>(test_struct) {
             Ok(mut input) => {
                 let schema_res = derive_avro_schema(&mut input);
-                let expected_token_stream = r#"let mut schema_fields = Vec :: 
with_capacity (1usize) ; schema_fields . push (:: apache_avro :: schema :: 
RecordField { name : "a3" . to_string () , doc : Some ("a doc" . into ()) , 
default : Some (serde_json :: from_str ("123") . expect (format ! ("Invalid 
JSON: {:?}" , "123") . as_str ())) , aliases : Some (vec ! ["a1" . into () , 
"a2" . into ()]) , schema : apache_avro :: schema :: Schema :: Int , order : :: 
apache_avro :: schema :: Recor [...]
+                let expected_token_stream = r#"let mut schema_fields = Vec :: 
with_capacity (1usize) ; schema_fields . push (:: apache_avro :: schema :: 
RecordField { name : "a3" . to_string () , doc : Some ("a doc" . into ()) , 
default : Some (serde_json :: from_str ("123") . expect (format ! ("Invalid 
JSON: {:?}" , "123") . as_str ())) , aliases : Some (vec ! ["a1" . into () , 
"a2" . into ()]) , schema : < i32 as apache_avro :: AvroSchemaComponent > :: 
get_schema_in_ctxt (named_schemas [...]
                 let schema_token_stream = schema_res.unwrap().to_string();
                 assert!(schema_token_stream.contains(expected_token_stream));
             }
@@ -700,7 +675,7 @@ mod tests {
         match syn::parse2::<DeriveInput>(test_struct) {
             Ok(mut input) => {
                 let schema_res = derive_avro_schema(&mut input);
-                let expected_token_stream = r#"let name = apache_avro :: 
schema :: Name :: new ("A") . expect (& format ! ("Unable to parse schema name 
{}" , "A") [..]) . fully_qualified_name (enclosing_namespace) ; let 
enclosing_namespace = & name . namespace ; 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 () }) ;  [...]
+                let expected_token_stream = r#"let name = apache_avro :: 
schema :: Name :: new ("A") . expect (& format ! ("Unable to parse schema name 
{}" , "A") [..]) . fully_qualified_name (enclosing_namespace) ; let 
enclosing_namespace = & name . namespace ; 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 () }) ;  [...]
                 let schema_token_stream = schema_res.unwrap().to_string();
                 assert!(schema_token_stream.contains(expected_token_stream));
             }
@@ -744,7 +719,7 @@ mod tests {
         match syn::parse2::<DeriveInput>(test_struct) {
             Ok(mut input) => {
                 let schema_res = derive_avro_schema(&mut input);
-                let expected_token_stream = r#"let name = apache_avro :: 
schema :: Name :: new ("A") . expect (& format ! ("Unable to parse schema name 
{}" , "A") [..]) . fully_qualified_name (enclosing_namespace) ; let 
enclosing_namespace = & name . namespace ; 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 () }) ;  [...]
+                let expected_token_stream = r#"let name = apache_avro :: 
schema :: Name :: new ("A") . expect (& format ! ("Unable to parse schema name 
{}" , "A") [..]) . fully_qualified_name (enclosing_namespace) ; let 
enclosing_namespace = & name . namespace ; 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 () }) ;  [...]
                 let schema_token_stream = schema_res.unwrap().to_string();
                 assert!(schema_token_stream.contains(expected_token_stream));
             }
diff --git a/avro_derive/tests/derive.rs b/avro_derive/tests/derive.rs
index cf3be7e..ec8e705 100644
--- a/avro_derive/tests/derive.rs
+++ b/avro_derive/tests/derive.rs
@@ -1827,3 +1827,31 @@ fn avro_rs_247_serde_flatten_support_with_skip() {
         b: 321,
     });
 }
+
+#[test]
+fn avro_rs_401_do_not_match_typename() {
+    #[expect(nonstandard_style, reason = "It needs to be exactly this")]
+    type f32 = f64;
+
+    #[expect(dead_code, reason = "We only check the schema")]
+    #[derive(AvroSchema)]
+    struct Foo {
+        field: f32,
+    }
+
+    let schema = r#"
+    {
+        "type":"record",
+        "name":"Foo",
+        "fields": [
+            {
+                "name":"field",
+                "type":"double"
+            }
+        ]
+    }
+    "#;
+
+    let schema = Schema::parse_str(schema).unwrap();
+    assert_eq!(schema, Foo::get_schema());
+}

Reply via email to