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:38 UTC
[avro] 01/01: AVRO-3759: Add extra types for RecordSchema, EnumSchema, FixedSchema and DecimalSchema
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 {