You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2023/05/19 13:06:37 UTC

[avro] branch avro-3759-add-extra-types created (now a46786b4b)

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

mgrigorov pushed a change to branch avro-3759-add-extra-types
in repository https://gitbox.apache.org/repos/asf/avro.git


      at a46786b4b AVRO-3759: Add extra types for RecordSchema, EnumSchema, FixedSchema and DecimalSchema

This branch includes the following new commits:

     new a46786b4b AVRO-3759: Add extra types for RecordSchema, EnumSchema, FixedSchema and DecimalSchema

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[avro] 01/01: AVRO-3759: Add extra types for RecordSchema, EnumSchema, FixedSchema and DecimalSchema

Posted by mg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a46786b4b409b9e293a4ed88552421ff854eb1a8
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Fri May 19 16:05:43 2023 +0300

    AVRO-3759: Add extra types for RecordSchema, EnumSchema, FixedSchema and DecimalSchema
    
    Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
 lang/rust/avro/src/decode.rs               |  33 ++--
 lang/rust/avro/src/encode.rs               |  15 +-
 lang/rust/avro/src/schema.rs               | 234 +++++++++++++++--------------
 lang/rust/avro/src/schema_compatibility.rs |  34 ++---
 lang/rust/avro/src/types.rs                |  94 ++++++------
 lang/rust/avro/src/writer.rs               |  18 +--
 lang/rust/avro/tests/schema.rs             |  26 ++--
 lang/rust/avro_derive/src/lib.rs           |   8 +-
 lang/rust/avro_derive/tests/derive.rs      |  48 +++---
 9 files changed, 270 insertions(+), 240 deletions(-)

diff --git a/lang/rust/avro/src/decode.rs b/lang/rust/avro/src/decode.rs
index 4f9e7e945..31b76243a 100644
--- a/lang/rust/avro/src/decode.rs
+++ b/lang/rust/avro/src/decode.rs
@@ -18,7 +18,10 @@
 use crate::{
     decimal::Decimal,
     duration::Duration,
-    schema::{Name, Namespace, ResolvedSchema, Schema},
+    schema::{
+        DecimalSchema, EnumSchema, FixedSchema, Name, Namespace, RecordSchema, ResolvedSchema,
+        Schema,
+    },
     types::Value,
     util::{safe_len, zag_i32, zag_i64},
     AvroResult, Error,
@@ -98,7 +101,7 @@ pub(crate) fn decode_internal<R: Read, S: Borrow<Schema>>(
                 }
             }
         }
-        Schema::Decimal { ref inner, .. } => match &**inner {
+        Schema::Decimal(DecimalSchema { ref inner, .. }) => match &**inner {
             Schema::Fixed { .. } => {
                 match decode_internal(inner, names, enclosing_namespace, reader)? {
                     Value::Fixed(_, bytes) => Ok(Value::Decimal(Decimal::from(bytes))),
@@ -164,7 +167,7 @@ pub(crate) fn decode_internal<R: Read, S: Borrow<Schema>>(
                 }
             }
         }
-        Schema::Fixed { size, .. } => {
+        Schema::Fixed(FixedSchema { size, .. }) => {
             let mut buf = vec![0u8; size];
             reader
                 .read_exact(&mut buf)
@@ -232,11 +235,11 @@ pub(crate) fn decode_internal<R: Read, S: Borrow<Schema>>(
             }
             Err(io_err) => Err(io_err),
         },
-        Schema::Record {
+        Schema::Record(RecordSchema {
             ref name,
             ref fields,
             ..
-        } => {
+        }) => {
             let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
             // Benchmarks indicate ~10% improvement using this method.
             let mut items = Vec::with_capacity(fields.len());
@@ -254,7 +257,7 @@ pub(crate) fn decode_internal<R: Read, S: Borrow<Schema>>(
             }
             Ok(Value::Record(items))
         }
-        Schema::Enum { ref symbols, .. } => {
+        Schema::Enum(EnumSchema { ref symbols, .. }) => {
             Ok(if let Value::Int(raw_index) = decode_int(reader)? {
                 let index = usize::try_from(raw_index)
                     .map_err(|e| Error::ConvertI32ToUsize(e, raw_index))?;
@@ -293,7 +296,7 @@ mod tests {
     use crate::{
         decode::decode,
         encode::{encode, tests::success},
-        schema::Schema,
+        schema::{DecimalSchema, FixedSchema, Schema},
         types::{
             Value,
             Value::{Array, Int, Map},
@@ -339,18 +342,18 @@ mod tests {
     fn test_negative_decimal_value() {
         use crate::{encode::encode, schema::Name};
         use num_bigint::ToBigInt;
-        let inner = Box::new(Schema::Fixed {
+        let inner = Box::new(Schema::Fixed(FixedSchema {
             size: 2,
             doc: None,
             name: Name::new("decimal").unwrap(),
             aliases: None,
             attributes: Default::default(),
-        });
-        let schema = Schema::Decimal {
+        }));
+        let schema = Schema::Decimal(DecimalSchema {
             inner,
             precision: 4,
             scale: 2,
-        };
+        });
         let bigint = (-423).to_bigint().unwrap();
         let value = Value::Decimal(Decimal::from(bigint.to_signed_bytes_be()));
 
@@ -366,18 +369,18 @@ mod tests {
     fn test_decode_decimal_with_bigger_than_necessary_size() {
         use crate::{encode::encode, schema::Name};
         use num_bigint::ToBigInt;
-        let inner = Box::new(Schema::Fixed {
+        let inner = Box::new(Schema::Fixed(FixedSchema {
             size: 13,
             name: Name::new("decimal").unwrap(),
             aliases: None,
             doc: None,
             attributes: Default::default(),
-        });
-        let schema = Schema::Decimal {
+        }));
+        let schema = Schema::Decimal(DecimalSchema {
             inner,
             precision: 4,
             scale: 2,
-        };
+        });
         let value = Value::Decimal(Decimal::from(
             ((-423).to_bigint().unwrap()).to_signed_bytes_be(),
         ));
diff --git a/lang/rust/avro/src/encode.rs b/lang/rust/avro/src/encode.rs
index 40f4ee0f7..94436b86f 100644
--- a/lang/rust/avro/src/encode.rs
+++ b/lang/rust/avro/src/encode.rs
@@ -16,7 +16,10 @@
 // under the License.
 
 use crate::{
-    schema::{Name, Namespace, ResolvedSchema, Schema, SchemaKind},
+    schema::{
+        DecimalSchema, EnumSchema, FixedSchema, Name, Namespace, RecordSchema, ResolvedSchema,
+        Schema, SchemaKind,
+    },
     types::{Value, ValueKind},
     util::{zig_i32, zig_i64},
     AvroResult, Error,
@@ -78,8 +81,8 @@ pub(crate) fn encode_internal<S: Borrow<Schema>>(
         Value::Float(x) => buffer.extend_from_slice(&x.to_le_bytes()),
         Value::Double(x) => buffer.extend_from_slice(&x.to_le_bytes()),
         Value::Decimal(decimal) => match schema {
-            Schema::Decimal { inner, .. } => match *inner.clone() {
-                Schema::Fixed { size, .. } => {
+            Schema::Decimal(DecimalSchema { inner, .. }) => match *inner.clone() {
+                Schema::Fixed(FixedSchema { size, .. }) => {
                     let bytes = decimal.to_sign_extended_bytes_with_len(size).unwrap();
                     let num_bytes = bytes.len();
                     if num_bytes != size {
@@ -125,7 +128,7 @@ pub(crate) fn encode_internal<S: Borrow<Schema>>(
             Schema::String | Schema::Uuid => {
                 encode_bytes(s, buffer);
             }
-            Schema::Enum { ref symbols, .. } => {
+            Schema::Enum(EnumSchema { ref symbols, .. }) => {
                 if let Some(index) = symbols.iter().position(|item| item == s) {
                     encode_int(index as i32, buffer);
                 } else {
@@ -194,12 +197,12 @@ pub(crate) fn encode_internal<S: Borrow<Schema>>(
             }
         }
         Value::Record(fields) => {
-            if let Schema::Record {
+            if let Schema::Record(RecordSchema {
                 ref name,
                 fields: ref schema_fields,
                 ref lookup,
                 ..
-            } = *schema
+            }) = *schema
             {
                 let record_namespace = name.fully_qualified_name(enclosing_namespace).namespace;
                 for (name, value) in fields.iter() {
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index a035a55ca..e5f3c69cb 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -98,43 +98,14 @@ pub enum Schema {
     /// A `union` Avro schema.
     Union(UnionSchema),
     /// A `record` Avro schema.
-    ///
-    /// The `lookup` table maps field names to their position in the `Vec`
-    /// of `fields`.
-    Record {
-        name: Name,
-        aliases: Aliases,
-        doc: Documentation,
-        fields: Vec<RecordField>,
-        lookup: BTreeMap<String, usize>,
-        attributes: BTreeMap<String, Value>,
-    },
+    Record(RecordSchema),
     /// An `enum` Avro schema.
-    Enum {
-        name: Name,
-        aliases: Aliases,
-        doc: Documentation,
-        symbols: Vec<String>,
-        attributes: BTreeMap<String, Value>,
-    },
+    Enum(EnumSchema),
     /// A `fixed` Avro schema.
-    Fixed {
-        name: Name,
-        aliases: Aliases,
-        doc: Documentation,
-        size: usize,
-        attributes: BTreeMap<String, Value>,
-    },
+    Fixed(FixedSchema),
     /// Logical type which represents `Decimal` values. The underlying type is serialized and
     /// deserialized as `Schema::Bytes` or `Schema::Fixed`.
-    ///
-    /// `scale` defaults to 0 and is an integer greater than or equal to 0 and `precision` is an
-    /// integer greater than 0.
-    Decimal {
-        precision: DecimalMetadata,
-        scale: DecimalMetadata,
-        inner: Box<Schema>,
-    },
+    Decimal(DecimalSchema),
     /// A universally unique identifier, annotating a string.
     Uuid,
     /// Logical type which represents the number of days since the unix epoch.
@@ -452,7 +423,7 @@ impl<'s> ResolvedSchema<'s> {
                         Self::from_internal(vec![schema], names_ref, enclosing_namespace)?
                     }
                 }
-                Schema::Enum { name, .. } | Schema::Fixed { name, .. } => {
+                Schema::Enum(EnumSchema { name, .. }) | Schema::Fixed(FixedSchema { name, .. }) => {
                     let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
                     if names_ref
                         .insert(fully_qualified_name.clone(), schema)
@@ -461,7 +432,7 @@ impl<'s> ResolvedSchema<'s> {
                         return Err(Error::AmbiguousSchemaDefinition(fully_qualified_name));
                     }
                 }
-                Schema::Record { name, fields, .. } => {
+                Schema::Record(RecordSchema { name, fields, .. }) => {
                     let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
                     if names_ref
                         .insert(fully_qualified_name.clone(), schema)
@@ -530,7 +501,7 @@ impl ResolvedOwnedSchema {
                 }
                 Ok(())
             }
-            Schema::Enum { name, .. } | Schema::Fixed { name, .. } => {
+            Schema::Enum(EnumSchema { name, .. }) | Schema::Fixed(FixedSchema { name, .. }) => {
                 let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
                 if names
                     .insert(fully_qualified_name.clone(), schema.clone())
@@ -541,7 +512,7 @@ impl ResolvedOwnedSchema {
                     Ok(())
                 }
             }
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
                 if names
                     .insert(fully_qualified_name.clone(), schema.clone())
@@ -666,6 +637,45 @@ impl RecordField {
     }
 }
 
+/// The `lookup` table maps field names to their position in the `Vec`
+/// of `fields`.
+#[derive(Debug, Clone)]
+pub struct RecordSchema {
+    pub name: Name,
+    pub aliases: Aliases,
+    pub doc: Documentation,
+    pub fields: Vec<RecordField>,
+    pub lookup: BTreeMap<String, usize>,
+    pub attributes: BTreeMap<String, Value>,
+}
+
+#[derive(Debug, Clone)]
+pub struct EnumSchema {
+    pub name: Name,
+    pub aliases: Aliases,
+    pub doc: Documentation,
+    pub symbols: Vec<String>,
+    pub attributes: BTreeMap<String, Value>,
+}
+
+#[derive(Debug, Clone)]
+pub struct FixedSchema {
+    pub name: Name,
+    pub aliases: Aliases,
+    pub doc: Documentation,
+    pub size: usize,
+    pub attributes: BTreeMap<String, Value>,
+}
+
+/// `scale` defaults to 0 and is an integer greater than or equal to 0 and `precision` is an
+/// integer greater than 0.
+#[derive(Debug, Clone)]
+pub struct DecimalSchema {
+    pub precision: DecimalMetadata,
+    pub scale: DecimalMetadata,
+    pub inner: Box<Schema>,
+}
+
 #[derive(Debug, Clone)]
 pub struct UnionSchema {
     pub(crate) schemas: Vec<Schema>,
@@ -851,9 +861,9 @@ impl Schema {
     /// Returns the custom attributes (metadata) if the schema supports them.
     pub fn custom_attributes(&self) -> Option<&BTreeMap<String, Value>> {
         match self {
-            Schema::Record { attributes, .. }
-            | Schema::Enum { attributes, .. }
-            | Schema::Fixed { attributes, .. } => Some(attributes),
+            Schema::Record(RecordSchema { attributes, .. })
+            | Schema::Enum(EnumSchema { attributes, .. })
+            | Schema::Fixed(FixedSchema { attributes, .. }) => Some(attributes),
             _ => None,
         }
     }
@@ -862,9 +872,9 @@ impl Schema {
     pub fn name(&self) -> Option<&Name> {
         match self {
             Schema::Ref { ref name, .. }
-            | Schema::Record { ref name, .. }
-            | Schema::Enum { ref name, .. }
-            | Schema::Fixed { ref name, .. } => Some(name),
+            | Schema::Record(RecordSchema { ref name, .. })
+            | Schema::Enum(EnumSchema { ref name, .. })
+            | Schema::Fixed(FixedSchema { ref name, .. }) => Some(name),
             _ => None,
         }
     }
@@ -960,9 +970,9 @@ impl Parser {
     ) -> AvroResult<Schema> {
         fn get_schema_ref(parsed: &Schema) -> Schema {
             match &parsed {
-                Schema::Record { ref name, .. }
-                | Schema::Enum { ref name, .. }
-                | Schema::Fixed { ref name, .. } => Schema::Ref { name: name.clone() },
+                Schema::Record(RecordSchema { ref name, .. })
+                | Schema::Enum(EnumSchema { ref name, .. })
+                | Schema::Fixed(FixedSchema { ref name, .. }) => Schema::Ref { name: name.clone() },
                 _ => parsed.clone(),
             }
         }
@@ -1116,11 +1126,11 @@ impl Parser {
 
                     let (precision, scale) = Self::parse_precision_and_scale(complex)?;
 
-                    return Ok(Schema::Decimal {
+                    return Ok(Schema::Decimal(DecimalSchema {
                         precision,
                         scale,
                         inner,
-                    });
+                    }));
                 }
                 "uuid" => {
                     logical_verify_type(complex, &[SchemaKind::String], self, enclosing_namespace)?;
@@ -1313,14 +1323,14 @@ impl Parser {
             }
         }
 
-        let schema = Schema::Record {
+        let schema = Schema::Record(RecordSchema {
             name,
             aliases: aliases.clone(),
             doc: complex.doc(),
             fields,
             lookup,
             attributes: self.get_custom_attributes(complex, vec!["fields"]),
-        };
+        });
 
         self.register_parsed_schema(&fully_qualified_name, &schema, &aliases);
         Ok(schema)
@@ -1387,13 +1397,13 @@ impl Parser {
             existing_symbols.insert(symbol);
         }
 
-        let schema = Schema::Enum {
+        let schema = Schema::Enum(EnumSchema {
             name,
             aliases: aliases.clone(),
             doc: complex.doc(),
             symbols,
             attributes: self.get_custom_attributes(complex, vec!["symbols"]),
-        };
+        });
 
         self.register_parsed_schema(&fully_qualified_name, &schema, &aliases);
 
@@ -1490,13 +1500,13 @@ impl Parser {
         let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
         let aliases = fix_aliases_namespace(complex.aliases(), &name.namespace);
 
-        let schema = Schema::Fixed {
+        let schema = Schema::Fixed(FixedSchema {
             name,
             aliases: aliases.clone(),
             doc,
             size: size as usize,
             attributes: self.get_custom_attributes(complex, vec!["size"]),
-        };
+        });
 
         self.register_parsed_schema(&fully_qualified_name, &schema, &aliases);
 
@@ -1573,13 +1583,13 @@ impl Serialize for Schema {
                 }
                 seq.end()
             }
-            Schema::Record {
+            Schema::Record(RecordSchema {
                 ref name,
                 ref aliases,
                 ref doc,
                 ref fields,
                 ..
-            } => {
+            }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", "record")?;
                 if let Some(ref n) = name.namespace {
@@ -1595,12 +1605,12 @@ impl Serialize for Schema {
                 map.serialize_entry("fields", fields)?;
                 map.end()
             }
-            Schema::Enum {
+            Schema::Enum(EnumSchema {
                 ref name,
                 ref symbols,
                 ref aliases,
                 ..
-            } => {
+            }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", "enum")?;
                 if let Some(ref n) = name.namespace {
@@ -1614,13 +1624,13 @@ impl Serialize for Schema {
                 }
                 map.end()
             }
-            Schema::Fixed {
+            Schema::Fixed(FixedSchema {
                 ref name,
                 ref doc,
                 ref size,
                 ref aliases,
                 ..
-            } => {
+            }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", "fixed")?;
                 if let Some(ref n) = name.namespace {
@@ -1637,11 +1647,11 @@ impl Serialize for Schema {
                 }
                 map.end()
             }
-            Schema::Decimal {
+            Schema::Decimal(DecimalSchema {
                 ref scale,
                 ref precision,
                 ref inner,
-            } => {
+            }) => {
                 let mut map = serializer.serialize_map(None)?;
                 map.serialize_entry("type", &*inner.clone())?;
                 map.serialize_entry("logicalType", "decimal")?;
@@ -1690,13 +1700,13 @@ impl Serialize for Schema {
 
                 // the Avro doesn't indicate what the name of the underlying fixed type of a
                 // duration should be or typically is.
-                let inner = Schema::Fixed {
+                let inner = Schema::Fixed(FixedSchema {
                     name: Name::new("duration").unwrap(),
                     aliases: None,
                     doc: None,
                     size: 12,
                     attributes: Default::default(),
-                };
+                });
                 map.serialize_entry("type", &inner)?;
                 map.serialize_entry("logicalType", "duration")?;
                 map.end()
@@ -2185,7 +2195,7 @@ mod tests {
             .unwrap()
             .clone();
 
-        let schema_c_expected = Schema::Record {
+        let schema_c_expected = Schema::Record(RecordSchema {
             name: Name::new("C").unwrap(),
             aliases: None,
             doc: None,
@@ -2211,7 +2221,7 @@ mod tests {
             }],
             lookup: BTreeMap::from_iter(vec![("field_one".to_string(), 0)]),
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(schema_c, schema_c_expected);
     }
@@ -2237,7 +2247,7 @@ mod tests {
         let schema_a = list.first().unwrap().clone();
 
         match schema_a {
-            Schema::Record { fields, .. } => {
+            Schema::Record(RecordSchema { fields, .. }) => {
                 let f1 = fields.get(0);
 
                 let ref_schema = Schema::Ref {
@@ -2277,7 +2287,7 @@ mod tests {
             .unwrap()
             .clone();
 
-        let schema_option_a_expected = Schema::Record {
+        let schema_option_a_expected = Schema::Record(RecordSchema {
             name: Name::new("OptionA").unwrap(),
             aliases: None,
             doc: None,
@@ -2301,7 +2311,7 @@ mod tests {
             }],
             lookup: BTreeMap::from_iter(vec![("field_one".to_string(), 0)]),
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(schema_option_a, schema_option_a_expected);
     }
@@ -2326,7 +2336,7 @@ mod tests {
         lookup.insert("a".to_owned(), 0);
         lookup.insert("b".to_owned(), 1);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name::new("test").unwrap(),
             aliases: None,
             doc: None,
@@ -2354,7 +2364,7 @@ mod tests {
             ],
             lookup,
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(parsed, expected);
     }
@@ -2390,7 +2400,7 @@ mod tests {
         node_lookup.insert("children".to_owned(), 1);
         node_lookup.insert("label".to_owned(), 0);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name::new("test").unwrap(),
             aliases: None,
             doc: None,
@@ -2399,7 +2409,7 @@ mod tests {
                 doc: None,
                 default: None,
                 aliases: None,
-                schema: Schema::Record {
+                schema: Schema::Record(RecordSchema {
                     name: Name::new("Node").unwrap(),
                     aliases: None,
                     doc: None,
@@ -2429,14 +2439,14 @@ mod tests {
                     ],
                     lookup: node_lookup,
                     attributes: Default::default(),
-                },
+                }),
                 order: RecordFieldOrder::Ascending,
                 position: 0,
                 custom_attributes: Default::default(),
             }],
             lookup,
             attributes: Default::default(),
-        };
+        });
         assert_eq!(schema, expected);
 
         let canonical_form = &schema.canonical_form();
@@ -2566,7 +2576,7 @@ mod tests {
         lookup.insert("value".to_owned(), 0);
         lookup.insert("next".to_owned(), 1);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name {
                 name: "LongList".to_owned(),
                 namespace: None,
@@ -2608,7 +2618,7 @@ mod tests {
             ],
             lookup,
             attributes: Default::default(),
-        };
+        });
         assert_eq!(schema, expected);
 
         let canonical_form = &schema.canonical_form();
@@ -2637,7 +2647,7 @@ mod tests {
         lookup.insert("value".to_owned(), 0);
         lookup.insert("next".to_owned(), 1);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name {
                 name: "record".to_owned(),
                 namespace: None,
@@ -2673,7 +2683,7 @@ mod tests {
             ],
             lookup,
             attributes: Default::default(),
-        };
+        });
         assert_eq!(schema, expected);
 
         let canonical_form = &schema.canonical_form();
@@ -2706,7 +2716,7 @@ mod tests {
         lookup.insert("enum".to_owned(), 0);
         lookup.insert("next".to_owned(), 1);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name {
                 name: "record".to_owned(),
                 namespace: None,
@@ -2719,7 +2729,7 @@ mod tests {
                     doc: None,
                     default: None,
                     aliases: None,
-                    schema: Schema::Enum {
+                    schema: Schema::Enum(EnumSchema {
                         name: Name {
                             name: "enum".to_owned(),
                             namespace: None,
@@ -2728,7 +2738,7 @@ mod tests {
                         doc: None,
                         symbols: vec!["one".to_string(), "two".to_string(), "three".to_string()],
                         attributes: Default::default(),
-                    },
+                    }),
                     order: RecordFieldOrder::Ascending,
                     position: 0,
                     custom_attributes: Default::default(),
@@ -2738,7 +2748,7 @@ mod tests {
                     doc: None,
                     default: None,
                     aliases: None,
-                    schema: Schema::Enum {
+                    schema: Schema::Enum(EnumSchema {
                         name: Name {
                             name: "enum".to_owned(),
                             namespace: None,
@@ -2747,7 +2757,7 @@ mod tests {
                         doc: None,
                         symbols: vec!["one".to_string(), "two".to_string(), "three".to_string()],
                         attributes: Default::default(),
-                    },
+                    }),
                     order: RecordFieldOrder::Ascending,
                     position: 1,
                     custom_attributes: Default::default(),
@@ -2755,7 +2765,7 @@ mod tests {
             ],
             lookup,
             attributes: Default::default(),
-        };
+        });
         assert_eq!(schema, expected);
 
         let canonical_form = &schema.canonical_form();
@@ -2788,7 +2798,7 @@ mod tests {
         lookup.insert("fixed".to_owned(), 0);
         lookup.insert("next".to_owned(), 1);
 
-        let expected = Schema::Record {
+        let expected = Schema::Record(RecordSchema {
             name: Name {
                 name: "record".to_owned(),
                 namespace: None,
@@ -2801,7 +2811,7 @@ mod tests {
                     doc: None,
                     default: None,
                     aliases: None,
-                    schema: Schema::Fixed {
+                    schema: Schema::Fixed(FixedSchema {
                         name: Name {
                             name: "fixed".to_owned(),
                             namespace: None,
@@ -2810,7 +2820,7 @@ mod tests {
                         doc: None,
                         size: 456,
                         attributes: Default::default(),
-                    },
+                    }),
                     order: RecordFieldOrder::Ascending,
                     position: 0,
                     custom_attributes: Default::default(),
@@ -2820,7 +2830,7 @@ mod tests {
                     doc: None,
                     default: None,
                     aliases: None,
-                    schema: Schema::Fixed {
+                    schema: Schema::Fixed(FixedSchema {
                         name: Name {
                             name: "fixed".to_owned(),
                             namespace: None,
@@ -2829,7 +2839,7 @@ mod tests {
                         doc: None,
                         size: 456,
                         attributes: Default::default(),
-                    },
+                    }),
                     order: RecordFieldOrder::Ascending,
                     position: 1,
                     custom_attributes: Default::default(),
@@ -2837,7 +2847,7 @@ mod tests {
             ],
             lookup,
             attributes: Default::default(),
-        };
+        });
         assert_eq!(schema, expected);
 
         let canonical_form = &schema.canonical_form();
@@ -2851,7 +2861,7 @@ mod tests {
             r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "hearts"]}"#,
         ).unwrap();
 
-        let expected = Schema::Enum {
+        let expected = Schema::Enum(EnumSchema {
             name: Name::new("Suit").unwrap(),
             aliases: None,
             doc: None,
@@ -2862,7 +2872,7 @@ mod tests {
                 "hearts".to_owned(),
             ],
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(expected, schema);
     }
@@ -2889,13 +2899,13 @@ mod tests {
     fn test_fixed_schema() {
         let schema = Schema::parse_str(r#"{"type": "fixed", "name": "test", "size": 16}"#).unwrap();
 
-        let expected = Schema::Fixed {
+        let expected = Schema::Fixed(FixedSchema {
             name: Name::new("test").unwrap(),
             aliases: None,
             doc: None,
             size: 16usize,
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(expected, schema);
     }
@@ -2907,13 +2917,13 @@ mod tests {
         )
         .unwrap();
 
-        let expected = Schema::Fixed {
+        let expected = Schema::Fixed(FixedSchema {
             name: Name::new("test").unwrap(),
             aliases: None,
             doc: Some(String::from("FixedSchema documentation")),
             size: 16usize,
             attributes: Default::default(),
-        };
+        });
 
         assert_eq!(expected, schema);
     }
@@ -2925,7 +2935,7 @@ mod tests {
                 .unwrap();
 
         let doc = match schema {
-            Schema::Enum { doc, .. } => doc,
+            Schema::Enum(EnumSchema { doc, .. }) => doc,
             _ => return,
         };
 
@@ -2939,7 +2949,7 @@ mod tests {
         ).unwrap();
 
         let doc = match schema {
-            Schema::Enum { doc, .. } => doc,
+            Schema::Enum(EnumSchema { doc, .. }) => doc,
             _ => None,
         };
 
@@ -3103,7 +3113,7 @@ mod tests {
     "#;
 
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, .. } = schema {
+        if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.name, "name");
             assert_eq!(name.namespace, Some("space".to_string()));
         } else {
@@ -3128,7 +3138,7 @@ mod tests {
     "#;
 
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, .. } = schema {
+        if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.namespace, Some("space1".to_string()));
         } else {
             panic!("Expected a record schema!");
@@ -3152,7 +3162,7 @@ mod tests {
     "#;
 
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, .. } = schema {
+        if let Schema::Record(RecordSchema { name, .. }) = schema {
             assert_eq!(name.namespace, Some("space2".to_string()));
         } else {
             panic!("Expected a record schema!");
@@ -3870,7 +3880,7 @@ mod tests {
         )
         .unwrap();
 
-        if let Schema::Record { ref aliases, .. } = schema {
+        if let Schema::Record(RecordSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be a record: {schema:?}");
@@ -3894,7 +3904,7 @@ mod tests {
         )
         .unwrap();
 
-        if let Schema::Enum { ref aliases, .. } = schema {
+        if let Schema::Enum(EnumSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be an enum: {schema:?}");
@@ -3916,7 +3926,7 @@ mod tests {
         )
         .unwrap();
 
-        if let Schema::Fixed { ref aliases, .. } = schema {
+        if let Schema::Fixed(FixedSchema { ref aliases, .. }) = schema {
             assert_avro_3512_aliases(aliases);
         } else {
             panic!("The Schema should be a fixed: {schema:?}");
@@ -4028,7 +4038,7 @@ mod tests {
         "#;
         let schema = Schema::parse_str(schema_str).unwrap();
 
-        if let Schema::Record { name, fields, .. } = schema {
+        if let Schema::Record(RecordSchema { name, fields, .. }) = schema {
             assert_eq!(name, Name::new("AccountEvent").unwrap());
 
             let field = &fields[0];
@@ -4187,7 +4197,7 @@ mod tests {
             Schema::parse_str(schema_str.replace("{{{}}}", CUSTOM_ATTRS_SUFFIX).as_str()).unwrap();
 
         match schema {
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 assert_eq!(name, Name::new("Rec").unwrap());
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
@@ -4215,7 +4225,7 @@ mod tests {
         let schema = Schema::parse_str(&schema_str).unwrap();
 
         match schema {
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 assert_eq!(name, Name::new("union_schema_test").unwrap());
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
@@ -4252,7 +4262,7 @@ mod tests {
         let schema = Schema::parse_str(&schema_str).unwrap();
 
         match schema {
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 assert_eq!(name, Name::new("union_schema_test").unwrap());
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
@@ -4288,7 +4298,7 @@ mod tests {
         let schema = Schema::parse_str(&schema_str).unwrap();
 
         match schema {
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 assert_eq!(name, Name::new("union_schema_test").unwrap());
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
@@ -4325,7 +4335,7 @@ mod tests {
         let schema = Schema::parse_str(&schema_str).unwrap();
 
         match schema {
-            Schema::Record { name, fields, .. } => {
+            Schema::Record(RecordSchema { name, fields, .. }) => {
                 assert_eq!(name, Name::new("union_schema_test").unwrap());
                 assert_eq!(fields.len(), 1);
                 let field = &fields[0];
@@ -4361,7 +4371,7 @@ mod tests {
         "#;
 
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { fields, .. } = schema {
+        if let Schema::Record(RecordSchema { fields, .. }) = schema {
             let num_field = &fields[0];
             assert_eq!(num_field.name, "num");
             assert_eq!(num_field.aliases, Some(vec!("num1".into(), "num2".into())));
diff --git a/lang/rust/avro/src/schema_compatibility.rs b/lang/rust/avro/src/schema_compatibility.rs
index b691041e5..aad8fde36 100644
--- a/lang/rust/avro/src/schema_compatibility.rs
+++ b/lang/rust/avro/src/schema_compatibility.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 //! Logic for checking schema compatibility
-use crate::schema::{Schema, SchemaKind};
+use crate::schema::{EnumSchema, FixedSchema, RecordSchema, Schema, SchemaKind};
 use std::{
     collections::{hash_map::DefaultHasher, HashSet},
     hash::Hasher,
@@ -88,13 +88,13 @@ impl Checker {
             SchemaKind::Union => self.match_union_schemas(writers_schema, readers_schema),
             SchemaKind::Enum => {
                 // reader's symbols must contain all writer's symbols
-                if let Schema::Enum {
+                if let Schema::Enum(EnumSchema {
                     symbols: w_symbols, ..
-                } = writers_schema
+                }) = writers_schema
                 {
-                    if let Schema::Enum {
+                    if let Schema::Enum(EnumSchema {
                         symbols: r_symbols, ..
-                    } = readers_schema
+                    }) = readers_schema
                     {
                         return !w_symbols.iter().any(|e| !r_symbols.contains(e));
                     }
@@ -121,15 +121,15 @@ impl Checker {
             return false;
         }
 
-        if let Schema::Record {
+        if let Schema::Record(RecordSchema {
             fields: w_fields,
             lookup: w_lookup,
             ..
-        } = writers_schema
+        }) = writers_schema
         {
-            if let Schema::Record {
+            if let Schema::Record(RecordSchema {
                 fields: r_fields, ..
-            } = readers_schema
+            }) = readers_schema
             {
                 for field in r_fields.iter() {
                     if let Some(pos) = w_lookup.get(&field.name) {
@@ -219,8 +219,8 @@ impl SchemaCompatibility {
 
             match r_type {
                 SchemaKind::Record => {
-                    if let Schema::Record { name: w_name, .. } = writers_schema {
-                        if let Schema::Record { name: r_name, .. } = readers_schema {
+                    if let Schema::Record(RecordSchema { name: w_name, .. }) = writers_schema {
+                        if let Schema::Record(RecordSchema { name: r_name, .. }) = readers_schema {
                             return w_name.fullname(None) == r_name.fullname(None);
                         } else {
                             unreachable!("readers_schema should have been Schema::Record")
@@ -230,21 +230,21 @@ impl SchemaCompatibility {
                     }
                 }
                 SchemaKind::Fixed => {
-                    if let Schema::Fixed {
+                    if let Schema::Fixed(FixedSchema {
                         name: w_name,
                         aliases: _,
                         doc: _w_doc,
                         size: w_size,
                         attributes: _,
-                    } = writers_schema
+                    }) = writers_schema
                     {
-                        if let Schema::Fixed {
+                        if let Schema::Fixed(FixedSchema {
                             name: r_name,
                             aliases: _,
                             doc: _r_doc,
                             size: r_size,
                             attributes: _,
-                        } = readers_schema
+                        }) = readers_schema
                         {
                             return w_name.fullname(None) == r_name.fullname(None)
                                 && w_size == r_size;
@@ -256,8 +256,8 @@ impl SchemaCompatibility {
                     }
                 }
                 SchemaKind::Enum => {
-                    if let Schema::Enum { name: w_name, .. } = writers_schema {
-                        if let Schema::Enum { name: r_name, .. } = readers_schema {
+                    if let Schema::Enum(EnumSchema { name: w_name, .. }) = writers_schema {
+                        if let Schema::Enum(EnumSchema { name: r_name, .. }) = readers_schema {
                             return w_name.fullname(None) == r_name.fullname(None);
                         } else {
                             unreachable!("readers_schema should have been Schema::Enum")
diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs
index ee322b331..d44826be1 100644
--- a/lang/rust/avro/src/types.rs
+++ b/lang/rust/avro/src/types.rs
@@ -20,8 +20,8 @@ use crate::{
     decimal::Decimal,
     duration::Duration,
     schema::{
-        Name, NamesRef, Namespace, Precision, RecordField, ResolvedSchema, Scale, Schema,
-        SchemaKind, UnionSchema,
+        DecimalSchema, EnumSchema, FixedSchema, Name, NamesRef, Namespace, Precision, RecordField,
+        RecordSchema, ResolvedSchema, Scale, Schema, SchemaKind, UnionSchema,
     },
     AvroResult, Error,
 };
@@ -221,11 +221,11 @@ impl<'a> Record<'a> {
     /// If the `Schema` is not a `Schema::Record` variant, `None` will be returned.
     pub fn new(schema: &Schema) -> Option<Record> {
         match *schema {
-            Schema::Record {
+            Schema::Record(RecordSchema {
                 fields: ref schema_fields,
                 lookup: ref schema_lookup,
                 ..
-            } => {
+            }) => {
                 let mut fields = Vec::with_capacity(schema_fields.len());
                 for schema_field in schema_fields.iter() {
                     fields.push((schema_field.name.clone(), Value::Null));
@@ -282,7 +282,7 @@ impl From<JsonValue> for Value {
 }
 
 /// Convert Avro values to Json values
-impl std::convert::TryFrom<Value> for JsonValue {
+impl TryFrom<Value> for JsonValue {
     type Error = crate::error::Error;
     fn try_from(value: Value) -> AvroResult<Self> {
         match value {
@@ -415,7 +415,7 @@ impl Value {
             (&Value::Bytes(_), &Schema::Decimal { .. }) => None,
             (&Value::String(_), &Schema::String) => None,
             (&Value::String(_), &Schema::Uuid) => None,
-            (&Value::Fixed(n, _), &Schema::Fixed { size, .. }) => {
+            (&Value::Fixed(n, _), &Schema::Fixed(FixedSchema { size, .. })) => {
                 if n != size {
                     Some(format!(
                         "The value's size ({n}) is different than the schema's size ({size})"
@@ -424,7 +424,7 @@ impl Value {
                     None
                 }
             }
-            (Value::Bytes(b), &Schema::Fixed { size, .. }) => {
+            (Value::Bytes(b), &Schema::Fixed(FixedSchema { size, .. })) => {
                 if b.len() != size {
                     Some(format!(
                         "The bytes' length ({}) is different than the schema's size ({})",
@@ -446,14 +446,14 @@ impl Value {
             }
             // TODO: check precision against n
             (&Value::Fixed(_n, _), &Schema::Decimal { .. }) => None,
-            (Value::String(s), Schema::Enum { symbols, .. }) => {
+            (Value::String(s), Schema::Enum(EnumSchema { symbols, .. })) => {
                 if !symbols.contains(s) {
                     Some(format!("'{s}' is not a member of the possible symbols"))
                 } else {
                     None
                 }
             }
-            (&Value::Enum(i, ref s), Schema::Enum { symbols, .. }) => symbols
+            (&Value::Enum(i, ref s), Schema::Enum(EnumSchema { symbols, .. })) => symbols
                 .get(i as usize)
                 .map(|ref symbol| {
                     if symbol != &s {
@@ -487,7 +487,7 @@ impl Value {
                     )
                 })
             }
-            (Value::Record(record_fields), Schema::Record { fields, lookup, .. }) => {
+            (Value::Record(record_fields), Schema::Record(RecordSchema { fields, lookup, .. })) => {
                 let non_nullable_fields_count =
                     fields.iter().filter(|&rf| !rf.is_nullable()).count();
 
@@ -527,7 +527,7 @@ impl Value {
                         }
                     })
             }
-            (Value::Map(items), Schema::Record { fields, .. }) => {
+            (Value::Map(items), Schema::Record(RecordSchema { fields, .. })) => {
                 fields.iter().fold(None, |acc, field| {
                     if let Some(item) = items.get(&field.name) {
                         let res = item.validate_internal(&field.schema, names, enclosing_namespace);
@@ -598,19 +598,19 @@ impl Value {
             Schema::Double => self.resolve_double(),
             Schema::Bytes => self.resolve_bytes(),
             Schema::String => self.resolve_string(),
-            Schema::Fixed { size, .. } => self.resolve_fixed(size),
+            Schema::Fixed(FixedSchema { size, .. }) => self.resolve_fixed(size),
             Schema::Union(ref inner) => self.resolve_union(inner, names, enclosing_namespace),
-            Schema::Enum { ref symbols, .. } => self.resolve_enum(symbols),
+            Schema::Enum(EnumSchema { ref symbols, .. }) => self.resolve_enum(symbols),
             Schema::Array(ref inner) => self.resolve_array(inner, names, enclosing_namespace),
             Schema::Map(ref inner) => self.resolve_map(inner, names, enclosing_namespace),
-            Schema::Record { ref fields, .. } => {
+            Schema::Record(RecordSchema { ref fields, .. }) => {
                 self.resolve_record(fields, names, enclosing_namespace)
             }
-            Schema::Decimal {
+            Schema::Decimal(DecimalSchema {
                 scale,
                 precision,
                 ref inner,
-            } => self.resolve_decimal(precision, scale, inner),
+            }) => self.resolve_decimal(precision, scale, inner),
             Schema::Date => self.resolve_date(),
             Schema::TimeMillis => self.resolve_time_millis(),
             Schema::TimeMicros => self.resolve_time_micros(),
@@ -657,7 +657,7 @@ impl Value {
             return Err(Error::GetScaleAndPrecision { scale, precision });
         }
         match inner {
-            &Schema::Fixed { size, .. } => {
+            &Schema::Fixed(FixedSchema { size, .. }) => {
                 if max_prec_for_len(size)? < precision {
                     return Err(Error::GetScaleWithFixedSize { size, precision });
                 }
@@ -960,7 +960,7 @@ impl Value {
                     Some(value) => value,
                     None => match field.default {
                         Some(ref value) => match field.schema {
-                            Schema::Enum { ref symbols, .. } => {
+                            Schema::Enum(EnumSchema { ref symbols, .. }) => {
                                 Value::from(value.clone()).resolve_enum(symbols)?
                             }
                             Schema::Union(ref union_schema) => {
@@ -1106,7 +1106,7 @@ mod tests {
             ),
             (
                 Value::Record(vec![("unknown_field_name".to_string(), Value::Null)]),
-                Schema::Record {
+                Schema::Record(RecordSchema {
                     name: Name::new("record_name").unwrap(),
                     aliases: None,
                     doc: None,
@@ -1122,13 +1122,13 @@ mod tests {
                     }],
                     lookup: Default::default(),
                     attributes: Default::default(),
-                },
+                }),
                 false,
-                r#"Invalid value: Record([("unknown_field_name", Null)]) for schema: Record { name: Name { name: "record_name", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "field_name", doc: None, aliases: None, default: None, schema: Int, order: Ignore, position: 0, custom_attributes: {} }], lookup: {}, attributes: {} }. Reason: There is no schema field for field 'unknown_field_name'"#,
+                r#"Invalid value: Record([("unknown_field_name", Null)]) for schema: Record(RecordSchema { name: Name { name: "record_name", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "field_name", doc: None, aliases: None, default: None, schema: Int, order: Ignore, position: 0, custom_attributes: {} }], lookup: {}, attributes: {} }). Reason: There is no schema field for field 'unknown_field_name'"#,
             ),
             (
                 Value::Record(vec![("field_name".to_string(), Value::Null)]),
-                Schema::Record {
+                Schema::Record(RecordSchema {
                     name: Name::new("record_name").unwrap(),
                     aliases: None,
                     doc: None,
@@ -1146,9 +1146,9 @@ mod tests {
                     }],
                     lookup: [("field_name".to_string(), 0)].iter().cloned().collect(),
                     attributes: Default::default(),
-                },
+                }),
                 false,
-                r#"Invalid value: Record([("field_name", Null)]) for schema: Record { name: Name { name: "record_name", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "field_name", doc: None, aliases: None, default: None, schema: Ref { name: Name { name: "missing", namespace: None } }, order: Ignore, position: 0, custom_attributes: {} }], lookup: {"field_name": 0}, attributes: {} }. Reason: Unresolved schema reference: 'Name { name: "missing", namespace: None } [...]
+                r#"Invalid value: Record([("field_name", Null)]) for schema: Record(RecordSchema { name: Name { name: "record_name", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "field_name", doc: None, aliases: None, default: None, schema: Ref { name: Name { name: "missing", namespace: None } }, order: Ignore, position: 0, custom_attributes: {} }], lookup: {"field_name": 0}, attributes: {} }). Reason: Unresolved schema reference: 'Name { name: "missing", nam [...]
             ),
         ];
 
@@ -1170,13 +1170,13 @@ mod tests {
 
     #[test]
     fn validate_fixed() {
-        let schema = Schema::Fixed {
+        let schema = Schema::Fixed(FixedSchema {
             size: 4,
             name: Name::new("some_fixed").unwrap(),
             aliases: None,
             doc: None,
             attributes: Default::default(),
-        };
+        });
 
         assert!(Value::Fixed(4, vec![0, 0, 0, 0]).validate(&schema));
         let value = Value::Fixed(5, vec![0, 0, 0, 0, 0]);
@@ -1203,7 +1203,7 @@ mod tests {
 
     #[test]
     fn validate_enum() {
-        let schema = Schema::Enum {
+        let schema = Schema::Enum(EnumSchema {
             name: Name::new("some_enum").unwrap(),
             aliases: None,
             doc: None,
@@ -1214,7 +1214,7 @@ mod tests {
                 "clubs".to_string(),
             ],
             attributes: Default::default(),
-        };
+        });
 
         assert!(Value::Enum(0, "spades".to_string()).validate(&schema));
         assert!(Value::String("spades".to_string()).validate(&schema));
@@ -1249,7 +1249,7 @@ mod tests {
             .as_str(),
         );
 
-        let other_schema = Schema::Enum {
+        let other_schema = Schema::Enum(EnumSchema {
             name: Name::new("some_other_enum").unwrap(),
             aliases: None,
             doc: None,
@@ -1260,7 +1260,7 @@ mod tests {
                 "spades".to_string(),
             ],
             attributes: Default::default(),
-        };
+        });
 
         let value = Value::Enum(0, "spades".to_string());
         assert!(!value.validate(&other_schema));
@@ -1287,7 +1287,7 @@ mod tests {
         //      }
         //    ]
         // }
-        let schema = Schema::Record {
+        let schema = Schema::Record(RecordSchema {
             name: Name::new("some_record").unwrap(),
             aliases: None,
             doc: None,
@@ -1334,7 +1334,7 @@ mod tests {
             .cloned()
             .collect(),
             attributes: Default::default(),
-        };
+        });
 
         assert!(Value::Record(vec![
             ("a".to_string(), Value::Long(42i64)),
@@ -1354,7 +1354,7 @@ mod tests {
         ]);
         assert!(!value.validate(&schema));
         assert_logged(
-            r#"Invalid value: Record([("a", Boolean(false)), ("b", String("foo"))]) for schema: Record { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name: "c",  [...]
+            r#"Invalid value: Record([("a", Boolean(false)), ("b", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField  [...]
         );
 
         let value = Value::Record(vec![
@@ -1363,7 +1363,7 @@ mod tests {
         ]);
         assert!(!value.validate(&schema));
         assert_logged(
-            r#"Invalid value: Record([("a", Long(42)), ("c", String("foo"))]) for schema: Record { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name: "c", doc: N [...]
+            r#"Invalid value: Record([("a", Long(42)), ("c", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name [...]
         );
         assert_not_logged(
             r#"Invalid value: String("foo") for schema: Int. Reason: Unsupported value-schema combination"#,
@@ -1375,7 +1375,7 @@ mod tests {
         ]);
         assert!(!value.validate(&schema));
         assert_logged(
-            r#"Invalid value: Record([("a", Long(42)), ("d", String("foo"))]) for schema: Record { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name: "c", doc: N [...]
+            r#"Invalid value: Record([("a", Long(42)), ("d", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name [...]
         );
 
         let value = Value::Record(vec![
@@ -1386,7 +1386,7 @@ mod tests {
         ]);
         assert!(!value.validate(&schema));
         assert_logged(
-            r#"Invalid value: Record([("a", Long(42)), ("b", String("foo")), ("c", Null), ("d", Null)]) for schema: Record { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, Recor [...]
+            r#"Invalid value: Record([("a", Long(42)), ("b", String("foo")), ("c", Null), ("d", Null)]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes [...]
         );
 
         assert!(Value::Map(
@@ -1406,7 +1406,7 @@ mod tests {
         )
         .validate(&schema));
         assert_logged(
-            r#"Invalid value: Map({"d": Long(123)}) for schema: Record { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name: "c", doc: None, aliases: None, defaul [...]
+            r#"Invalid value: Map({"d": Long(123)}) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "a", doc: None, aliases: None, default: None, schema: Long, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "b", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 1, custom_attributes: {} }, RecordField { name: "c", doc: None, aliases: [...]
 Field with name '"b"' is not a member of the map items"#,
         );
 
@@ -1473,11 +1473,11 @@ Field with name '"b"' is not a member of the map items"#,
         let value = Value::Decimal(Decimal::from(vec![1, 2]));
         value
             .clone()
-            .resolve(&Schema::Decimal {
+            .resolve(&Schema::Decimal(DecimalSchema {
                 precision: 10,
                 scale: 4,
                 inner: Box::new(Schema::Bytes),
-            })
+            }))
             .unwrap();
         assert!(value.resolve(&Schema::String).is_err());
     }
@@ -1486,11 +1486,11 @@ Field with name '"b"' is not a member of the map items"#,
     fn resolve_decimal_invalid_scale() {
         let value = Value::Decimal(Decimal::from(vec![1]));
         assert!(value
-            .resolve(&Schema::Decimal {
+            .resolve(&Schema::Decimal(DecimalSchema {
                 precision: 2,
                 scale: 3,
                 inner: Box::new(Schema::Bytes),
-            })
+            }))
             .is_err());
     }
 
@@ -1498,11 +1498,11 @@ Field with name '"b"' is not a member of the map items"#,
     fn resolve_decimal_invalid_precision_for_length() {
         let value = Value::Decimal(Decimal::from((1u8..=8u8).rev().collect::<Vec<_>>()));
         assert!(value
-            .resolve(&Schema::Decimal {
+            .resolve(&Schema::Decimal(DecimalSchema {
                 precision: 1,
                 scale: 0,
                 inner: Box::new(Schema::Bytes),
-            })
+            }))
             .is_err());
     }
 
@@ -1511,17 +1511,17 @@ Field with name '"b"' is not a member of the map items"#,
         let value = Value::Decimal(Decimal::from(vec![1, 2]));
         assert!(value
             .clone()
-            .resolve(&Schema::Decimal {
+            .resolve(&Schema::Decimal(DecimalSchema {
                 precision: 10,
                 scale: 1,
-                inner: Box::new(Schema::Fixed {
+                inner: Box::new(Schema::Fixed(FixedSchema {
                     name: Name::new("decimal").unwrap(),
                     aliases: None,
                     size: 20,
                     doc: None,
                     attributes: Default::default(),
-                })
-            })
+                }))
+            }))
             .is_ok());
         assert!(value.resolve(&Schema::String).is_err());
     }
diff --git a/lang/rust/avro/src/writer.rs b/lang/rust/avro/src/writer.rs
index 795fd09f2..58d13d40f 100644
--- a/lang/rust/avro/src/writer.rs
+++ b/lang/rust/avro/src/writer.rs
@@ -632,7 +632,7 @@ mod tests {
     use crate::{
         decimal::Decimal,
         duration::{Days, Duration, Millis, Months},
-        schema::Name,
+        schema::{DecimalSchema, FixedSchema, Name},
         types::Record,
         util::zig_i64,
     };
@@ -781,21 +781,21 @@ mod tests {
     #[test]
     fn decimal_fixed() -> TestResult<()> {
         let size = 30;
-        let inner = Schema::Fixed {
+        let inner = Schema::Fixed(FixedSchema {
             name: Name::new("decimal").unwrap(),
             aliases: None,
             doc: None,
             size,
             attributes: Default::default(),
-        };
+        });
         let value = vec![0u8; size];
         logical_type_test(
             r#"{"type": {"type": "fixed", "size": 30, "name": "decimal"}, "logicalType": "decimal", "precision": 20, "scale": 5}"#,
-            &Schema::Decimal {
+            &Schema::Decimal(DecimalSchema {
                 precision: 20,
                 scale: 5,
                 inner: Box::new(inner.clone()),
-            },
+            }),
             Value::Decimal(Decimal::from(value.clone())),
             &inner,
             Value::Fixed(size, value),
@@ -808,11 +808,11 @@ mod tests {
         let value = vec![0u8; 10];
         logical_type_test(
             r#"{"type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 3}"#,
-            &Schema::Decimal {
+            &Schema::Decimal(DecimalSchema {
                 precision: 4,
                 scale: 3,
                 inner: Box::new(inner.clone()),
-            },
+            }),
             Value::Decimal(Decimal::from(value.clone())),
             &inner,
             value,
@@ -821,13 +821,13 @@ mod tests {
 
     #[test]
     fn duration() -> TestResult<()> {
-        let inner = Schema::Fixed {
+        let inner = Schema::Fixed(FixedSchema {
             name: Name::new("duration").unwrap(),
             aliases: None,
             doc: None,
             size: 12,
             attributes: Default::default(),
-        };
+        });
         let value = Value::Duration(Duration::new(
             Months::new(256),
             Days::new(512),
diff --git a/lang/rust/avro/tests/schema.rs b/lang/rust/avro/tests/schema.rs
index 95ba18c2f..5018dc5dd 100644
--- a/lang/rust/avro/tests/schema.rs
+++ b/lang/rust/avro/tests/schema.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 use apache_avro::{
-    schema::{Name, RecordField},
+    schema::{EnumSchema, FixedSchema, Name, RecordField, RecordSchema},
     to_avro_datum, to_value,
     types::{Record, Value},
     Codec, Error, Reader, Schema, Writer,
@@ -634,21 +634,21 @@ fn test_correct_recursive_extraction() {
         ]
     }"#;
     let outer_schema = Schema::parse_str(raw_outer_schema).unwrap();
-    if let Schema::Record {
+    if let Schema::Record(RecordSchema {
         fields: outer_fields,
         ..
-    } = outer_schema
+    }) = outer_schema
     {
         let inner_schema = &outer_fields[0].schema;
-        if let Schema::Record {
+        if let Schema::Record(RecordSchema {
             fields: inner_fields,
             ..
-        } = inner_schema
+        }) = inner_schema
         {
-            if let Schema::Record {
+            if let Schema::Record(RecordSchema {
                 name: recursive_type,
                 ..
-            } = &inner_fields[0].schema
+            }) = &inner_fields[0].schema
             {
                 assert_eq!("X", recursive_type.name.as_str());
             }
@@ -880,14 +880,14 @@ fn test_parse_reused_record_schema_by_fullname() {
     let schema = Schema::parse_str(schema_str);
     assert!(schema.is_ok());
     match schema.unwrap() {
-        Schema::Record {
+        Schema::Record(RecordSchema {
             ref name,
             aliases: _,
             doc: _,
             ref fields,
             lookup: _,
             attributes: _,
-        } => {
+        }) => {
             assert_eq!(name.fullname(None), "test.Weather", "Name does not match!");
 
             assert_eq!(fields.len(), 3, "The number of the fields is not correct!");
@@ -1199,9 +1199,9 @@ fn test_doc_attributes() {
     init();
     fn assert_doc(schema: &Schema) {
         match schema {
-            Schema::Enum { doc, .. } => assert!(doc.is_some()),
-            Schema::Record { doc, .. } => assert!(doc.is_some()),
-            Schema::Fixed { doc, .. } => assert!(doc.is_some()),
+            Schema::Enum(EnumSchema { doc, .. }) => assert!(doc.is_some()),
+            Schema::Record(RecordSchema { doc, .. }) => assert!(doc.is_some()),
+            Schema::Fixed(FixedSchema { doc, .. }) => assert!(doc.is_some()),
             Schema::String => (),
             _ => unreachable!("Unexpected schema type: {:?}", schema),
         }
@@ -1210,7 +1210,7 @@ fn test_doc_attributes() {
     for (raw_schema, _) in DOC_EXAMPLES.iter() {
         let original_schema = Schema::parse_str(raw_schema).unwrap();
         assert_doc(&original_schema);
-        if let Schema::Record { fields, .. } = original_schema {
+        if let Schema::Record(RecordSchema { fields, .. }) = original_schema {
             for f in fields {
                 assert_doc(&f.schema)
             }
diff --git a/lang/rust/avro_derive/src/lib.rs b/lang/rust/avro_derive/src/lib.rs
index 5f900473c..5e80e70af 100644
--- a/lang/rust/avro_derive/src/lib.rs
+++ b/lang/rust/avro_derive/src/lib.rs
@@ -190,14 +190,14 @@ fn get_data_struct_schema_def(
             .iter()
             .map(|field| (field.name.to_owned(), field.position))
             .collect();
-        apache_avro::schema::Schema::Record {
+        apache_avro::schema::Schema::Record(apache_avro::schema::RecordSchema {
             name,
             aliases: #record_aliases,
             doc: #record_doc,
             fields: schema_fields,
             lookup,
             attributes: Default::default(),
-        }
+        })
     })
 }
 
@@ -217,13 +217,13 @@ fn get_data_enum_schema_def(
             .map(|variant| variant.ident.to_string())
             .collect();
         Ok(quote! {
-            apache_avro::schema::Schema::Enum {
+            apache_avro::schema::Schema::Enum(apache_avro::schema::EnumSchema {
                 name: apache_avro::schema::Name::new(#full_schema_name).expect(&format!("Unable to parse enum name for schema {}", #full_schema_name)[..]),
                 aliases: #enum_aliases,
                 doc: #doc,
                 symbols: vec![#(#symbols.to_owned()),*],
                 attributes: Default::default(),
-            }
+            })
         })
     } else {
         Err(vec![syn::Error::new(
diff --git a/lang/rust/avro_derive/tests/derive.rs b/lang/rust/avro_derive/tests/derive.rs
index dcf599092..3dc217b6a 100644
--- a/lang/rust/avro_derive/tests/derive.rs
+++ b/lang/rust/avro_derive/tests/derive.rs
@@ -30,7 +30,7 @@ extern crate serde;
 
 #[cfg(test)]
 mod test_derive {
-    use apache_avro::schema::Alias;
+    use apache_avro::schema::{Alias, EnumSchema, RecordSchema};
     use std::{
         borrow::{Borrow, Cow},
         sync::Mutex,
@@ -144,7 +144,7 @@ mod test_derive {
         "#;
         let schema = Schema::parse_str(schema).unwrap();
         assert_eq!(schema, TestBasicNamespace::get_schema());
-        if let Schema::Record { name, .. } = TestBasicNamespace::get_schema() {
+        if let Schema::Record(RecordSchema { name, .. }) = TestBasicNamespace::get_schema() {
             assert_eq!("com.testing.namespace".to_owned(), name.namespace.unwrap())
         } else {
             panic!("TestBasicNamespace schema must be a record schema")
@@ -191,7 +191,9 @@ mod test_derive {
         "#;
         let schema = Schema::parse_str(schema).unwrap();
         assert_eq!(schema, TestComplexNamespace::get_schema());
-        if let Schema::Record { name, fields, .. } = TestComplexNamespace::get_schema() {
+        if let Schema::Record(RecordSchema { name, fields, .. }) =
+            TestComplexNamespace::get_schema()
+        {
             assert_eq!(
                 "com.testing.complex.namespace".to_owned(),
                 name.namespace.unwrap()
@@ -201,7 +203,7 @@ mod test_derive {
                 .filter(|field| field.name == "a")
                 .map(|field| &field.schema)
                 .next();
-            if let Some(Schema::Record { name, .. }) = inner_schema {
+            if let Some(Schema::Record(RecordSchema { name, .. })) = inner_schema {
                 assert_eq!(
                     "com.testing.namespace".to_owned(),
                     name.namespace.clone().unwrap()
@@ -944,7 +946,9 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, doc, .. } = TestBasicWithAttributes::get_schema() {
+        if let Schema::Record(RecordSchema { name, doc, .. }) =
+            TestBasicWithAttributes::get_schema()
+        {
             assert_eq!("com.testing.namespace".to_owned(), name.namespace.unwrap());
             assert_eq!("A Documented Record", doc.unwrap())
         } else {
@@ -987,7 +991,7 @@ mod test_derive {
         let schema = Schema::parse_str(schema).unwrap();
         let derived_schema = TestBasicWithOuterDocAttributes::get_schema();
         assert_eq!(&schema, &derived_schema);
-        if let Schema::Record { name, doc, .. } = derived_schema {
+        if let Schema::Record(RecordSchema { name, doc, .. }) = derived_schema {
             assert_eq!("com.testing.namespace".to_owned(), name.namespace.unwrap());
             assert_eq!("A Documented Record", doc.unwrap())
         } else {
@@ -1029,7 +1033,8 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, doc, .. } = TestBasicWithLargeDoc::get_schema() {
+        if let Schema::Record(RecordSchema { name, doc, .. }) = TestBasicWithLargeDoc::get_schema()
+        {
             assert_eq!("com.testing.namespace".to_owned(), name.namespace.unwrap());
             assert_eq!(
                 "A Documented Record\nthat spans\nmultiple lines",
@@ -1069,7 +1074,7 @@ mod test_derive {
         let schema = Schema::parse_str(schema).unwrap();
         let derived_schema = TestBasicWithBool::get_schema();
 
-        if let Schema::Record { name, .. } = derived_schema {
+        if let Schema::Record(RecordSchema { name, .. }) = derived_schema {
             assert_eq!("TestBasicWithBool", name.fullname(None))
         } else {
             panic!("TestBasicWithBool schema must be a record schema")
@@ -1100,7 +1105,7 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, .. } = TestBasicWithU32::get_schema() {
+        if let Schema::Record(RecordSchema { name, .. }) = TestBasicWithU32::get_schema() {
             assert_eq!("TestBasicWithU32", name.fullname(None))
         } else {
             panic!("TestBasicWithU32 schema must be a record schema")
@@ -1132,7 +1137,9 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, aliases, .. } = TestBasicStructWithAliases::get_schema() {
+        if let Schema::Record(RecordSchema { name, aliases, .. }) =
+            TestBasicStructWithAliases::get_schema()
+        {
             assert_eq!("TestBasicStructWithAliases", name.fullname(None));
             assert_eq!(
                 Some(vec![
@@ -1174,7 +1181,9 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, aliases, .. } = TestBasicStructWithAliases2::get_schema() {
+        if let Schema::Record(RecordSchema { name, aliases, .. }) =
+            TestBasicStructWithAliases2::get_schema()
+        {
             assert_eq!("TestBasicStructWithAliases2", name.fullname(None));
             assert_eq!(
                 Some(vec![
@@ -1213,7 +1222,9 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Enum { name, aliases, .. } = TestBasicEnumWithAliases::get_schema() {
+        if let Schema::Enum(EnumSchema { name, aliases, .. }) =
+            TestBasicEnumWithAliases::get_schema()
+        {
             assert_eq!("TestBasicEnumWithAliases", name.fullname(None));
             assert_eq!(
                 Some(vec![
@@ -1254,7 +1265,9 @@ mod test_derive {
         }
         "#;
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Enum { name, aliases, .. } = TestBasicEnumWithAliases2::get_schema() {
+        if let Schema::Enum(EnumSchema { name, aliases, .. }) =
+            TestBasicEnumWithAliases2::get_schema()
+        {
             assert_eq!("TestBasicEnumWithAliases2", name.fullname(None));
             assert_eq!(
                 Some(vec![
@@ -1358,7 +1371,8 @@ mod test_derive {
         "#;
 
         let schema = Schema::parse_str(schema).unwrap();
-        if let Schema::Record { name, fields, .. } = TestBasicStructWithDefaultValues::get_schema()
+        if let Schema::Record(RecordSchema { name, fields, .. }) =
+            TestBasicStructWithDefaultValues::get_schema()
         {
             assert_eq!("TestBasicStructWithDefaultValues", name.fullname(None));
             use serde_json::json;
@@ -1455,7 +1469,7 @@ mod test_derive {
 
         let schema = Schema::parse_str(schema).unwrap();
         let derived_schema = TestBasicStructWithSkipAttribute::get_schema();
-        if let Schema::Record { name, fields, .. } = &derived_schema {
+        if let Schema::Record(RecordSchema { name, fields, .. }) = &derived_schema {
             assert_eq!("TestBasicStructWithSkipAttribute", name.fullname(None));
             for field in fields {
                 match field.name.as_str() {
@@ -1522,7 +1536,7 @@ mod test_derive {
 
         let schema = Schema::parse_str(schema).unwrap();
         let derived_schema = TestBasicStructWithRenameAttribute::get_schema();
-        if let Schema::Record { name, fields, .. } = &derived_schema {
+        if let Schema::Record(RecordSchema { name, fields, .. }) = &derived_schema {
             assert_eq!("TestBasicStructWithRenameAttribute", name.fullname(None));
             for field in fields {
                 match field.name.as_str() {
@@ -1553,7 +1567,7 @@ mod test_derive {
         }
 
         let derived_schema = TestRawIdent::get_schema();
-        if let Schema::Record { fields, .. } = derived_schema {
+        if let Schema::Record(RecordSchema { fields, .. }) = derived_schema {
             let field = fields.get(0).expect("TestRawIdent must contain a field");
             assert_eq!(field.name, "type");
         } else {