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

mgrigorov pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/branch-1.11 by this push:
     new 708daa2b4 AVRO-3904: [Rust] return a Result when checking schema 
compatibility so the end users will have feedback in case or errors
708daa2b4 is described below

commit 708daa2b42ae6c37343cb8ad987303aaf8476afa
Author: Marcos Schroh <[email protected]>
AuthorDate: Tue Nov 28 10:02:49 2023 +0100

    AVRO-3904: [Rust] return a Result when checking schema compatibility so the 
end users will have feedback in case or errors
    
    Co-authored-by: Marcos Schroh <[email protected]>
    
    (cherry picked from commit 1cea6907a24773bdc5d7282fdd90e92b6aef0ab3)
---
 lang/rust/avro/.cargo/config.toml.disabled |  32 ++++
 lang/rust/avro/README.md                   |   4 +-
 lang/rust/avro/src/error.rs                |   6 +-
 lang/rust/avro/src/lib.rs                  |   4 +-
 lang/rust/avro/src/schema.rs               | 130 ++++++++-------
 lang/rust/avro/src/schema_compatibility.rs | 260 ++++++++++++++---------------
 lang/rust/avro/tests/test.rs               |  53 ++++++
 7 files changed, 288 insertions(+), 201 deletions(-)

diff --git a/lang/rust/avro/.cargo/config.toml.disabled 
b/lang/rust/avro/.cargo/config.toml.disabled
new file mode 100644
index 000000000..9084890b5
--- /dev/null
+++ b/lang/rust/avro/.cargo/config.toml.disabled
@@ -0,0 +1,32 @@
+[build]
+rustc-wrapper = '/home/martin/.cargo/bin/sccache'
+[target.x86_64-unknown-linux-gnu]
+rustflags = [
+    '-Clink-arg=-fuse-ld=lld',
+    '-Zshare-generics=y',
+]
+linker = '/usr/bin/clang'
+
+[target.x86_64-pc-windows-msvc]
+rustflags = ['-Zshare-generics=y']
+linker = 'rust-lld.exe'
+
+[target.x86_64-apple-darwin]
+rustflags = [
+    '-C',
+    'link-arg=-fuse-ld=/usr/local/bin/zld',
+    '-Zshare-generics=y',
+    '-Csplit-debuginfo=unpacked',
+]
+[profile.dev]
+opt-level = 0
+debug = 2
+incremental = true
+codegen-units = 512
+
+[profile.release]
+opt-level = 3
+debug = 0
+incremental = false
+codegen-units = 256
+split-debuginfo = '...'
diff --git a/lang/rust/avro/README.md b/lang/rust/avro/README.md
index 3a48806b7..b47e18045 100644
--- a/lang/rust/avro/README.md
+++ b/lang/rust/avro/README.md
@@ -636,7 +636,7 @@ use apache_avro::{Schema, 
schema_compatibility::SchemaCompatibility};
 
 let writers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"int"}"#).unwrap();
 let readers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"long"}"#).unwrap();
-assert_eq!(true, SchemaCompatibility::can_read(&writers_schema, 
&readers_schema));
+assert!(SchemaCompatibility::can_read(&writers_schema, 
&readers_schema).is_ok());
 ```
 
 2. Incompatible schemas (a long array schema cannot be read by an int array 
schema)
@@ -649,7 +649,7 @@ use apache_avro::{Schema, 
schema_compatibility::SchemaCompatibility};
 
 let writers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"long"}"#).unwrap();
 let readers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"int"}"#).unwrap();
-assert_eq!(false, SchemaCompatibility::can_read(&writers_schema, 
&readers_schema));
+assert!(SchemaCompatibility::can_read(&writers_schema, 
&readers_schema).is_err());
 ```
 ### Custom names validators
 
diff --git a/lang/rust/avro/src/error.rs b/lang/rust/avro/src/error.rs
index b436f403f..aafcd5dff 100644
--- a/lang/rust/avro/src/error.rs
+++ b/lang/rust/avro/src/error.rs
@@ -114,7 +114,7 @@ pub enum Error {
     GetScaleAndPrecision { scale: usize, precision: usize },
 
     #[error(
-        "Fixed type number of bytes {size} is not large enough to hold decimal 
values of precision {precision}"
+    "Fixed type number of bytes {size} is not large enough to hold decimal 
values of precision {precision}"
     )]
     GetScaleWithFixedSize { size: usize, precision: usize },
 
@@ -484,7 +484,7 @@ pub enum Error {
         supported_schema: Vec<SchemaKind>,
     },
     #[error(
-        "Internal buffer not drained properly. Re-initialize the single object 
writer struct!"
+    "Internal buffer not drained properly. Re-initialize the single object 
writer struct!"
     )]
     IllegalSingleObjectWriterState,
 
@@ -531,7 +531,7 @@ pub enum CompatibilityError {
     },
 
     #[error(
-        "Incompatible schemata! Unknown type for '{0}'. Make sure that the 
type is a valid one"
+    "Incompatible schemata! Unknown type for '{0}'. Make sure that the type is 
a valid one"
     )]
     Inconclusive(String),
 }
diff --git a/lang/rust/avro/src/lib.rs b/lang/rust/avro/src/lib.rs
index d84c76b07..5fc24692b 100644
--- a/lang/rust/avro/src/lib.rs
+++ b/lang/rust/avro/src/lib.rs
@@ -749,7 +749,7 @@
 //!
 //! let writers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"int"}"#).unwrap();
 //! let readers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"long"}"#).unwrap();
-//! assert_eq!(true, SchemaCompatibility::can_read(&writers_schema, 
&readers_schema));
+//! assert!(SchemaCompatibility::can_read(&writers_schema, 
&readers_schema).is_ok());
 //! ```
 //!
 //! 2. Incompatible schemas (a long array schema cannot be read by an int 
array schema)
@@ -762,7 +762,7 @@
 //!
 //! let writers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"long"}"#).unwrap();
 //! let readers_schema = Schema::parse_str(r#"{"type": "array", 
"items":"int"}"#).unwrap();
-//! assert_eq!(false, SchemaCompatibility::can_read(&writers_schema, 
&readers_schema));
+//! assert!(SchemaCompatibility::can_read(&writers_schema, 
&readers_schema).is_err());
 //! ```
 //! ## Custom names validators
 //!
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index bd7d05eef..9e1eb1e5b 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -960,7 +960,7 @@ impl UnionSchema {
                     enclosing_namespace,
                     &collected_names,
                 )
-                .expect("Schema didn't successfully parse");
+                    .expect("Schema didn't successfully parse");
                 let resolved_names = resolved_schema.names_ref;
 
                 // extend known schemas with just resolved names
@@ -1951,13 +1951,13 @@ impl Serialize for Schema {
                 seq.end()
             }
             Schema::Record(RecordSchema {
-                ref name,
-                ref aliases,
-                ref doc,
-                ref fields,
-                ref attributes,
-                ..
-            }) => {
+                               ref name,
+                               ref aliases,
+                               ref doc,
+                               ref fields,
+                               ref attributes,
+                               ..
+                           }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", "record")?;
                 if let Some(ref n) = name.namespace {
@@ -1977,12 +1977,12 @@ impl Serialize for Schema {
                 map.end()
             }
             Schema::Enum(EnumSchema {
-                ref name,
-                ref symbols,
-                ref aliases,
-                ref attributes,
-                ..
-            }) => {
+                             ref name,
+                             ref symbols,
+                             ref aliases,
+                             ref attributes,
+                             ..
+                         }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", "enum")?;
                 if let Some(ref n) = name.namespace {
@@ -2005,10 +2005,10 @@ impl Serialize for Schema {
                 map.end()
             }
             Schema::Decimal(DecimalSchema {
-                ref scale,
-                ref precision,
-                ref inner,
-            }) => {
+                                ref scale,
+                                ref precision,
+                                ref inner,
+                            }) => {
                 let mut map = serializer.serialize_map(None)?;
                 match inner.as_ref() {
                     Schema::Fixed(fixed_schema) => {
@@ -2311,7 +2311,7 @@ pub mod derive {
     /// ```
     pub trait AvroSchemaComponent {
         fn get_schema_in_ctxt(named_schemas: &mut Names, enclosing_namespace: 
&Namespace)
-            -> Schema;
+                              -> Schema;
     }
 
     impl<T> AvroSchema for T
@@ -4806,6 +4806,44 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn avro_3649_default_notintfirst() -> TestResult {
+        let schema_str = String::from(
+            r#"
+            {
+                "type": "record",
+                "name": "union_schema_test",
+                "fields": [
+                    {"name": "a", "type": ["string", "int"], "default": 123}
+                ]
+            }
+        "#,
+        );
+
+        let schema = Schema::parse_str(&schema_str)?;
+
+        match schema {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
+                assert_eq!(name, Name::new("union_schema_test")?);
+                assert_eq!(fields.len(), 1);
+                let field = &fields[0];
+                assert_eq!(&field.name, "a");
+                assert_eq!(&field.default, &Some(json!(123)));
+                match &field.schema {
+                    Schema::Union(union) => {
+                        assert_eq!(union.variants().len(), 2);
+                        assert_eq!(union.variants()[0], Schema::String);
+                        assert_eq!(union.variants()[1], Schema::Int);
+                    }
+                    _ => panic!("Expected Schema::Union"),
+                }
+            }
+            _ => panic!("Expected Schema::Record"),
+        }
+
+        Ok(())
+    }
+
     #[test]
     fn avro_3709_parsing_of_record_field_aliases() -> TestResult {
         let schema = r#"
@@ -4861,7 +4899,7 @@ mod tests {
                     "type": "Bar"
                 }
             ]
-        } 
+        }
         "#;
 
         #[derive(
@@ -5691,42 +5729,6 @@ mod tests {
         Ok(())
     }
 
-    #[test]
-    fn avro_3649_default_notintfirst() {
-        let schema_str = String::from(
-            r#"
-            {
-                "type": "record",
-                "name": "union_schema_test",
-                "fields": [
-                    {"name": "a", "type": ["string", "int"], "default": 123}
-                ]
-            }
-        "#,
-        );
-
-        let schema = Schema::parse_str(&schema_str).unwrap();
-
-        match schema {
-            Schema::Record(RecordSchema { name, fields, .. }) => {
-                assert_eq!(name, Name::new("union_schema_test").unwrap());
-                assert_eq!(fields.len(), 1);
-                let field = &fields[0];
-                assert_eq!(&field.name, "a");
-                assert_eq!(&field.default, &Some(json!(123)));
-                match &field.schema {
-                    Schema::Union(union) => {
-                        assert_eq!(union.variants().len(), 2);
-                        assert_eq!(union.variants()[0], Schema::String);
-                        assert_eq!(union.variants()[1], Schema::Int);
-                    }
-                    _ => panic!("Expected Schema::Union"),
-                }
-            }
-            _ => panic!("Expected Schema::Record"),
-        }
-    }
-
     #[test]
     fn test_avro_3851_validate_default_value_of_simple_record_field() -> 
TestResult {
         let schema_str = r#"
@@ -5748,7 +5750,7 @@ mod tests {
             "ns.record1".to_string(),
             r#""int""#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5791,7 +5793,7 @@ mod tests {
             
r#"{"name":"ns.record2","type":"record","fields":[{"name":"f1_1","type":"int"}]}"#
                 .to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5828,7 +5830,7 @@ mod tests {
             "ns.record1".to_string(),
             
r#"{"name":"ns.enum1","type":"enum","symbols":["a","b","c"]}"#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5865,7 +5867,7 @@ mod tests {
             "ns.record1".to_string(),
             r#"{"name":"ns.fixed1","type":"fixed","size":3}"#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5899,7 +5901,7 @@ mod tests {
             "ns.record1".to_string(),
             r#"{"type":"array","items":"int"}"#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5933,7 +5935,7 @@ mod tests {
             "ns.record1".to_string(),
             r#"{"type":"map","values":"string"}"#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -5978,7 +5980,7 @@ mod tests {
             "ns.record1".to_string(),
             r#""ns.record2""#.to_string(),
         )
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
@@ -6023,7 +6025,7 @@ mod tests {
             symbol: "d".to_string(),
             symbols: vec!["a".to_string(), "b".to_string(), "c".to_string()],
         }
-        .to_string();
+            .to_string();
         let result = Schema::parse_str(schema_str);
         assert!(result.is_err());
         let err = result
diff --git a/lang/rust/avro/src/schema_compatibility.rs 
b/lang/rust/avro/src/schema_compatibility.rs
index 63c1ca847..083be7b9f 100644
--- a/lang/rust/avro/src/schema_compatibility.rs
+++ b/lang/rust/avro/src/schema_compatibility.rs
@@ -86,17 +86,17 @@ impl Checker {
 
         if w_type != SchemaKind::Union
             && (r_type.is_primitive()
-                || r_type == SchemaKind::Fixed
-                || r_type == SchemaKind::Uuid
-                || r_type == SchemaKind::Date
-                || r_type == SchemaKind::TimeMillis
-                || r_type == SchemaKind::TimeMicros
-                || r_type == SchemaKind::TimestampMillis
-                || r_type == SchemaKind::TimestampMicros
-                || r_type == SchemaKind::TimestampNanos
-                || r_type == SchemaKind::LocalTimestampMillis
-                || r_type == SchemaKind::LocalTimestampMicros
-                || r_type == SchemaKind::LocalTimestampNanos)
+            || r_type == SchemaKind::Fixed
+            || r_type == SchemaKind::Uuid
+            || r_type == SchemaKind::Date
+            || r_type == SchemaKind::TimeMillis
+            || r_type == SchemaKind::TimeMicros
+            || r_type == SchemaKind::TimestampMillis
+            || r_type == SchemaKind::TimestampMicros
+            || r_type == SchemaKind::TimestampNanos
+            || r_type == SchemaKind::LocalTimestampMillis
+            || r_type == SchemaKind::LocalTimestampMicros
+            || r_type == SchemaKind::LocalTimestampNanos)
         {
             return Ok(());
         }
@@ -140,12 +140,12 @@ impl Checker {
             SchemaKind::Enum => {
                 // reader's symbols must contain all writer's symbols
                 if let Schema::Enum(EnumSchema {
-                    symbols: w_symbols, ..
-                }) = writers_schema
+                                        symbols: w_symbols, ..
+                                    }) = writers_schema
                 {
                     if let Schema::Enum(EnumSchema {
-                        symbols: r_symbols, ..
-                    }) = readers_schema
+                                            symbols: r_symbols, ..
+                                        }) = readers_schema
                     {
                         if w_symbols.iter().all(|e| r_symbols.contains(e)) {
                             return Ok(());
@@ -184,14 +184,14 @@ impl Checker {
         }
 
         if let Schema::Record(RecordSchema {
-            fields: w_fields,
-            lookup: w_lookup,
-            ..
-        }) = writers_schema
+                                  fields: w_fields,
+                                  lookup: w_lookup,
+                                  ..
+                              }) = writers_schema
         {
             if let Schema::Record(RecordSchema {
-                fields: r_fields, ..
-            }) = readers_schema
+                                      fields: r_fields, ..
+                                  }) = readers_schema
             {
                 for field in r_fields.iter() {
                     // get all field names in a vector (field.name + aliases)
@@ -389,22 +389,22 @@ impl SchemaCompatibility {
                 }
                 SchemaKind::Fixed => {
                     if let Schema::Fixed(FixedSchema {
-                        name: w_name,
-                        aliases: _,
-                        doc: _w_doc,
-                        size: w_size,
-                        default: _w_default,
-                        attributes: _,
-                    }) = writers_schema
+                                             name: w_name,
+                                             aliases: _,
+                                             doc: _w_doc,
+                                             size: w_size,
+                                             default: _w_default,
+                                             attributes: _,
+                                         }) = writers_schema
                     {
                         if let Schema::Fixed(FixedSchema {
-                            name: r_name,
-                            aliases: _,
-                            doc: _r_doc,
-                            size: r_size,
-                            default: _r_default,
-                            attributes: _,
-                        }) = readers_schema
+                                                 name: r_name,
+                                                 aliases: _,
+                                                 doc: _r_doc,
+                                                 size: r_size,
+                                                 default: _r_default,
+                                                 attributes: _,
+                                             }) = readers_schema
                         {
                             return (w_name.name == r_name.name && w_size == 
r_size)
                                 .then_some(())
@@ -582,14 +582,14 @@ mod tests {
         Schema::parse_str(
             r#"{"type":"record", "name":"Record1", "fields":[{"name":"a", 
"type":"int"}]}"#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn a_long_record1_schema() -> Schema {
         Schema::parse_str(
             r#"{"type":"record", "name":"Record1", "fields":[{"name":"a", 
"type":"long"}]}"#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn a_int_b_int_record1_schema() -> Schema {
@@ -630,7 +630,7 @@ mod tests {
       ]}
 "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn union_schema(schemas: Vec<Schema>) -> Schema {
@@ -743,70 +743,70 @@ mod tests {
     #[rstest]
     // Record type test
     #[case(
-        r#"{"type": "record", "name": "record_a", "fields": [{"type": "long", 
"name": "date"}]}"#,
-        r#"{"type": "record", "name": "record_a", "fields": [{"type": "long", 
"name": "date", "default": 18181}]}"#
+    r#"{"type": "record", "name": "record_a", "fields": [{"type": "long", 
"name": "date"}]}"#,
+    r#"{"type": "record", "name": "record_a", "fields": [{"type": "long", 
"name": "date", "default": 18181}]}"#
     )]
     // Fixed type test
     #[case(
-        r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
-        r#"{"type": "fixed", "name": "EmployeeId", "size": 16, "default": 
"u00ffffffffffffx"}"#
+    r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
+    r#"{"type": "fixed", "name": "EmployeeId", "size": 16, "default": 
"u00ffffffffffffx"}"#
     )]
     // Enum type test
     #[case(
-        r#"{"type": "enum", "name":"Enum1", "symbols": ["A","B"]}"#,
-        r#"{"type": "enum", "name":"Enum1", "symbols": ["A","B", "C"], 
"default": "C"}"#
+    r#"{"type": "enum", "name":"Enum1", "symbols": ["A","B"]}"#,
+    r#"{"type": "enum", "name":"Enum1", "symbols": ["A","B", "C"], "default": 
"C"}"#
     )]
     // Map type test
     #[case(
-        r#"{"type": "map", "values": "int"}"#,
-        r#"{"type": "map", "values": "long"}"#
+    r#"{"type": "map", "values": "int"}"#,
+    r#"{"type": "map", "values": "long"}"#
     )]
     // Date type
     #[case(r#"{"type": "int"}"#, r#"{"type": "int", "logicalType": "date"}"#)]
     // time-millis type
     #[case(
-        r#"{"type": "int"}"#,
-        r#"{"type": "int", "logicalType": "time-millis"}"#
+    r#"{"type": "int"}"#,
+    r#"{"type": "int", "logicalType": "time-millis"}"#
     )]
     // time-millis type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "time-micros"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "time-micros"}"#
     )]
     // timetimestamp-nanos type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "timestamp-nanos"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "timestamp-nanos"}"#
     )]
     // timestamp-millis type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "timestamp-millis"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "timestamp-millis"}"#
     )]
     // timestamp-micros type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "timestamp-micros"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "timestamp-micros"}"#
     )]
     // local-timestamp-millis type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "local-timestamp-millis"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "local-timestamp-millis"}"#
     )]
     // local-timestamp-micros type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "local-timestamp-micros"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "local-timestamp-micros"}"#
     )]
     // local-timestamp-nanos type
     #[case(
-        r#"{"type": "long"}"#,
-        r#"{"type": "long", "logicalType": "local-timestamp-nanos"}"#
+    r#"{"type": "long"}"#,
+    r#"{"type": "long", "logicalType": "local-timestamp-nanos"}"#
     )]
     // Array type test
     #[case(
-        r#"{"type": "array", "items": "int"}"#,
-        r#"{"type": "array", "items": "long"}"#
+    r#"{"type": "array", "items": "int"}"#,
+    r#"{"type": "array", "items": "long"}"#
     )]
     fn test_avro_3950_match_schemas_ok(
         #[case] writer_schema_str: &str,
@@ -827,8 +827,8 @@ mod tests {
     )]
     // Fixed type test
     #[case(
-        r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
-        r#"{"type": "fixed", "name": "EmployeeId", "size": 20}"#,
+    r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
+    r#"{"type": "fixed", "name": "EmployeeId", "size": 20}"#,
         CompatibilityError::FixedMismatch
     )]
     // Enum type test
@@ -842,16 +842,16 @@ mod tests {
         r#"{"type":"map", "values": "long"}"#,
         r#"{"type":"map", "values": "int"}"#,
         CompatibilityError::TypeExpected {schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::TimeMicros,
-            SchemaKind::TimestampMillis,
-            SchemaKind::TimestampMicros,
-            SchemaKind::TimestampNanos,
-            SchemaKind::LocalTimestampMillis,
-            SchemaKind::LocalTimestampMicros,
-            SchemaKind::LocalTimestampNanos,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::TimeMicros,
+        SchemaKind::TimestampMillis,
+        SchemaKind::TimestampMicros,
+        SchemaKind::TimestampNanos,
+        SchemaKind::LocalTimestampMillis,
+        SchemaKind::LocalTimestampMicros,
+        SchemaKind::LocalTimestampNanos,
         ]}
     )]
     // Array type test
@@ -859,16 +859,16 @@ mod tests {
         r#"{"type": "array", "items": "long"}"#,
         r#"{"type": "array", "items": "int"}"#,
         CompatibilityError::TypeExpected {schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::TimeMicros,
-            SchemaKind::TimestampMillis,
-            SchemaKind::TimestampMicros,
-            SchemaKind::TimestampNanos,
-            SchemaKind::LocalTimestampMillis,
-            SchemaKind::LocalTimestampMicros,
-            SchemaKind::LocalTimestampNanos,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::TimeMicros,
+        SchemaKind::TimestampMillis,
+        SchemaKind::TimestampMicros,
+        SchemaKind::TimestampNanos,
+        SchemaKind::LocalTimestampMillis,
+        SchemaKind::LocalTimestampMicros,
+        SchemaKind::LocalTimestampNanos,
         ]}
     )]
     // Date type test
@@ -876,9 +876,9 @@ mod tests {
         r#"{"type": "string"}"#,
         r#"{"type": "int", "logicalType": "date"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::String,
-            SchemaKind::Bytes,
-            SchemaKind::Uuid,
+        SchemaKind::String,
+        SchemaKind::Bytes,
+        SchemaKind::Uuid,
         ]}
     )]
     // time-millis type
@@ -886,9 +886,9 @@ mod tests {
         r#"{"type": "string"}"#,
         r#"{"type": "int", "logicalType": "time-millis"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::String,
-            SchemaKind::Bytes,
-            SchemaKind::Uuid,
+        SchemaKind::String,
+        SchemaKind::Bytes,
+        SchemaKind::Uuid,
         ]}
     )]
     // time-millis type
@@ -896,12 +896,12 @@ mod tests {
         r#"{"type": "int"}"#,
         r#"{"type": "long", "logicalType": "time-micros"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Int,
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::Date,
-            SchemaKind::TimeMillis
+        SchemaKind::Int,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::Date,
+        SchemaKind::TimeMillis
         ]}
     )]
     // timestamp-nanos type. This test should fail because it is not supported 
on schema parse_complex
@@ -922,12 +922,12 @@ mod tests {
         r#"{"type": "int"}"#,
         r#"{"type": "long", "logicalType": "timestamp-millis"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Int,
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::Date,
-            SchemaKind::TimeMillis
+        SchemaKind::Int,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::Date,
+        SchemaKind::TimeMillis
         ]}
     )]
     // timestamp-micros type
@@ -935,12 +935,12 @@ mod tests {
         r#"{"type": "int"}"#,
         r#"{"type": "long", "logicalType": "timestamp-micros"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Int,
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::Date,
-            SchemaKind::TimeMillis
+        SchemaKind::Int,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::Date,
+        SchemaKind::TimeMillis
         ]}
     )]
     // local-timestamp-millis type
@@ -948,12 +948,12 @@ mod tests {
         r#"{"type": "int"}"#,
         r#"{"type": "long", "logicalType": "local-timestamp-millis"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Int,
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::Date,
-            SchemaKind::TimeMillis
+        SchemaKind::Int,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::Date,
+        SchemaKind::TimeMillis
         ]}
     )]
     // local-timestamp-micros type
@@ -961,12 +961,12 @@ mod tests {
         r#"{"type": "int"}"#,
         r#"{"type": "long", "logicalType": "local-timestamp-micros"}"#,
         CompatibilityError::TypeExpected{schema_type: 
String::from("readers_schema"), expected_type: vec![
-            SchemaKind::Int,
-            SchemaKind::Long,
-            SchemaKind::Float,
-            SchemaKind::Double,
-            SchemaKind::Date,
-            SchemaKind::TimeMillis
+        SchemaKind::Int,
+        SchemaKind::Long,
+        SchemaKind::Float,
+        SchemaKind::Double,
+        SchemaKind::Date,
+        SchemaKind::TimeMillis
         ]}
     )]
     // local-timestamp-nanos type. This test should fail because it is not 
supported on schema parse_complex
@@ -984,8 +984,8 @@ mod tests {
     // )]
     // When comparing different types we always get Inconclusive
     #[case(
-        r#"{"type": "record", "name":"record_b", "fields": [{"type": "long", 
"name": "date"}]}"#,
-        r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
+    r#"{"type": "record", "name":"record_b", "fields": [{"type": "long", 
"name": "date"}]}"#,
+    r#"{"type": "fixed", "name": "EmployeeId", "size": 16}"#,
         CompatibilityError::Inconclusive(String::from("writers_schema"))
     )]
     fn test_avro_3950_match_schemas_error(
@@ -1082,7 +1082,7 @@ mod tests {
       ]}
 "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     #[test]
@@ -1282,7 +1282,7 @@ mod tests {
       ]}
     "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn point_2d_fullname_schema() -> Schema {
@@ -1294,7 +1294,7 @@ mod tests {
       ]}
     "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn point_3d_no_default_schema() -> Schema {
@@ -1307,7 +1307,7 @@ mod tests {
       ]}
     "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn point_3d_schema() -> Schema {
@@ -1320,7 +1320,7 @@ mod tests {
       ]}
     "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     fn point_3d_match_name_schema() -> Schema {
@@ -1333,7 +1333,7 @@ mod tests {
       ]}
     "#,
         )
-        .unwrap()
+            .unwrap()
     }
 
     #[test]
diff --git a/lang/rust/avro/tests/test.rs b/lang/rust/avro/tests/test.rs
new file mode 100644
index 000000000..96185a3a8
--- /dev/null
+++ b/lang/rust/avro/tests/test.rs
@@ -0,0 +1,53 @@
+use apache_avro::{
+    schema_equality::{set_schemata_equality_comparator, SchemataEq, 
StructFieldEq},
+    types::Record,
+    Codec, Schema, Writer,
+};
+use apache_avro_test_helper::TestResult;
+use bigdecimal::BigDecimal;
+use num_bigint::BigInt;
+
+#[test]
+#[ignore]
+fn test_11111() -> TestResult {
+    let schema_str = r#"
+    {
+      "type": "record",
+      "name": "test",
+      "fields": [
+        {
+          "name": "field_name",
+          "type": "bytes",
+          "logicalType": "decimal", "precision": 4,    "scale": 2
+        }
+      ]
+    }
+    "#;
+    let schema = Schema::parse_str(schema_str)?;
+
+    let mut record = Record::new(&schema).unwrap();
+    let val = BigDecimal::new(BigInt::from(12), 2);
+    record.put("field_name", val);
+
+    let codec = Codec::Null;
+    let mut writer = Writer::builder()
+        .schema(&schema)
+        .codec(codec)
+        .writer(Vec::new())
+        .build();
+
+    writer.append(record.clone())?;
+
+    Ok(())
+}
+
+#[test]
+fn test_avro_3939_22222() -> Result<(), Box<dyn SchemataEq>> {
+    let a = StructFieldEq {
+        include_attributes: false,
+    };
+
+    set_schemata_equality_comparator(Box::new(a))?;
+
+    Ok(())
+}

Reply via email to