This is an automated email from the ASF dual-hosted git repository. kriskras99 pushed a commit to branch feat/schema_debug in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit ae4ca870aee245a8f845dff3a0df03a697b20097 Author: Kriskras99 <[email protected]> AuthorDate: Wed Feb 25 22:32:46 2026 +0100 feat: Custom `Debug` implementation for `*Schema` types This makes error messages significantly more readable, by not displaying values that are `None` or custom attributes that are empty. --- avro/src/schema/mod.rs | 98 +++++++++++++++++++++++++++++++-- avro/src/schema/record/field.rs | 28 +++++++++- avro/src/schema/record/schema.rs | 25 ++++++++- avro/src/schema/union.rs | 13 ++++- avro/src/types.rs | 38 ++++++------- avro/src/writer.rs | 2 +- avro/tests/serde_human_readable_true.rs | 4 +- 7 files changed, 177 insertions(+), 31 deletions(-) diff --git a/avro/src/schema/mod.rs b/avro/src/schema/mod.rs index e733ea1..5f5d81c 100644 --- a/avro/src/schema/mod.rs +++ b/avro/src/schema/mod.rs @@ -48,6 +48,7 @@ use serde::{ ser::{Error as _, SerializeMap, SerializeSeq}, }; use serde_json::{Map, Value as JsonValue}; +use std::fmt::Formatter; use std::{ collections::{BTreeMap, HashMap, HashSet}, fmt, @@ -164,20 +165,56 @@ pub enum Schema { Ref { name: Name }, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, PartialEq)] pub struct MapSchema { pub types: Box<Schema>, pub default: Option<HashMap<String, Value>>, pub attributes: BTreeMap<String, JsonValue>, } -#[derive(Clone, Debug, PartialEq)] +impl Debug for MapSchema { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_struct("MapSchema"); + debug.field("types", &self.types); + if let Some(default) = &self.default { + debug.field("default", default); + } + if !self.attributes.is_empty() { + debug.field("attributes", &self.attributes); + } + if self.default.is_none() || self.attributes.is_empty() { + debug.finish_non_exhaustive() + } else { + debug.finish() + } + } +} + +#[derive(Clone, PartialEq)] pub struct ArraySchema { pub items: Box<Schema>, pub default: Option<Vec<Value>>, pub attributes: BTreeMap<String, JsonValue>, } +impl Debug for ArraySchema { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_struct("ArraySchema"); + debug.field("items", &self.items); + if let Some(default) = &self.default { + debug.field("default", default); + } + if !self.attributes.is_empty() { + debug.field("attributes", &self.attributes); + } + if self.default.is_none() || self.attributes.is_empty() { + debug.finish_non_exhaustive() + } else { + debug.finish() + } + } +} + impl PartialEq for Schema { /// Assess equality of two `Schema` based on [Parsing Canonical Form]. /// @@ -252,7 +289,7 @@ impl From<&types::Value> for SchemaKind { } /// A description of an Enum schema. -#[derive(bon::Builder, Debug, Clone)] +#[derive(bon::Builder, Clone)] pub struct EnumSchema { /// The name of the schema pub name: Name, @@ -271,8 +308,37 @@ pub struct EnumSchema { pub attributes: BTreeMap<String, JsonValue>, } +impl Debug for EnumSchema { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_struct("EnumSchema"); + debug.field("name", &self.name); + if let Some(aliases) = &self.aliases { + debug.field("aliases", aliases); + } + if let Some(doc) = &self.doc { + debug.field("doc", doc); + } + debug.field("symbols", &self.symbols); + if let Some(default) = &self.default { + debug.field("default", default); + } + if !self.attributes.is_empty() { + debug.field("attributes", &self.attributes); + } + if self.aliases.is_none() + || self.doc.is_none() + || self.default.is_none() + || self.attributes.is_empty() + { + debug.finish_non_exhaustive() + } else { + debug.finish() + } + } +} + /// A description of a Fixed schema. -#[derive(bon::Builder, Debug, Clone)] +#[derive(bon::Builder, Clone)] pub struct FixedSchema { /// The name of the schema pub name: Name, @@ -289,6 +355,28 @@ pub struct FixedSchema { pub attributes: BTreeMap<String, JsonValue>, } +impl Debug for FixedSchema { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_struct("FixedSchema"); + debug.field("name", &self.name); + if let Some(aliases) = &self.aliases { + debug.field("aliases", aliases); + } + if let Some(doc) = &self.doc { + debug.field("doc", doc); + } + debug.field("size", &self.size); + if !self.attributes.is_empty() { + debug.field("attributes", &self.attributes); + } + if self.aliases.is_none() || self.doc.is_none() || !self.attributes.is_empty() { + debug.finish_non_exhaustive() + } else { + debug.finish() + } + } +} + impl FixedSchema { fn serialize_to_map<S>(&self, mut map: S::SerializeMap) -> Result<S::SerializeMap, S::Error> where @@ -4401,7 +4489,7 @@ mod tests { }) ); assert_logged( - r#"Ignoring uuid logical type for a Fixed schema because its size (6) is not 16! Schema: Fixed(FixedSchema { name: Name { name: "FixedUUID", namespace: None }, aliases: None, doc: None, size: 6, attributes: {} })"#, + r#"Ignoring uuid logical type for a Fixed schema because its size (6) is not 16! Schema: Fixed(FixedSchema { name: Name { name: "FixedUUID", namespace: None }, size: 6, .. })"#, ); Ok(()) diff --git a/avro/src/schema/record/field.rs b/avro/src/schema/record/field.rs index f237f1b..cb1b6dd 100644 --- a/avro/src/schema/record/field.rs +++ b/avro/src/schema/record/field.rs @@ -26,11 +26,12 @@ use serde::ser::SerializeMap; use serde::{Serialize, Serializer}; use serde_json::{Map, Value}; use std::collections::BTreeMap; +use std::fmt::{Debug, Formatter}; use std::str::FromStr; use strum::EnumString; /// Represents a `field` in a `record` Avro schema. -#[derive(bon::Builder, Clone, Debug, PartialEq)] +#[derive(bon::Builder, Clone, PartialEq)] pub struct RecordField { /// Name of the field. #[builder(into)] @@ -59,6 +60,31 @@ pub struct RecordField { pub custom_attributes: BTreeMap<String, Value>, } +impl Debug for RecordField { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut debug = f.debug_struct("RecordField"); + debug.field("name", &self.name); + if let Some(doc) = &self.doc { + debug.field("doc", &doc); + } + if let Some(aliases) = &self.aliases { + debug.field("aliases", &aliases); + } + if let Some(default) = &self.default { + debug.field("default", &default); + } + debug.field("schema", &self.schema); + // This field is ignored as it currently has no effect + // debug.field("order", &self.order); + debug.field("position", &self.position); + if !self.custom_attributes.is_empty() { + debug.field("custom_attributes", &self.custom_attributes); + } + // As we are always skipping self.order, always show the .. + debug.finish_non_exhaustive() + } +} + /// Represents any valid order for a `field` in a `record` Avro schema. #[derive(Clone, Debug, Eq, PartialEq, EnumString)] #[strum(serialize_all = "kebab_case")] diff --git a/avro/src/schema/record/schema.rs b/avro/src/schema/record/schema.rs index b14bad7..816a6bf 100644 --- a/avro/src/schema/record/schema.rs +++ b/avro/src/schema/record/schema.rs @@ -18,9 +18,10 @@ use crate::schema::{Aliases, Documentation, Name, RecordField}; use serde_json::Value; use std::collections::BTreeMap; +use std::fmt::{Debug, Formatter}; /// A description of a Record schema. -#[derive(bon::Builder, Debug, Clone)] +#[derive(bon::Builder, Clone)] pub struct RecordSchema { /// The name of the schema pub name: Name, @@ -42,6 +43,28 @@ pub struct RecordSchema { pub attributes: BTreeMap<String, Value>, } +impl Debug for RecordSchema { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut debug = f.debug_struct("RecordSchema"); + debug.field("name", &self.name); + if let Some(aliases) = &self.aliases { + debug.field("default", aliases); + } + if let Some(doc) = &self.doc { + debug.field("doc", doc); + } + debug.field("fields", &self.fields); + if !self.attributes.is_empty() { + debug.field("attributes", &self.attributes); + } + if self.aliases.is_none() || self.doc.is_none() || self.attributes.is_empty() { + debug.finish_non_exhaustive() + } else { + debug.finish() + } + } +} + impl<S: record_schema_builder::State> RecordSchemaBuilder<S> { /// Try to set a Name from the given string. pub fn try_name<T>( diff --git a/avro/src/schema/union.rs b/avro/src/schema/union.rs index 7510a13..bca79aa 100644 --- a/avro/src/schema/union.rs +++ b/avro/src/schema/union.rs @@ -21,10 +21,10 @@ use crate::schema::{Name, Namespace, ResolvedSchema, Schema, SchemaKind}; use crate::types; use std::borrow::Borrow; use std::collections::{BTreeMap, HashMap, HashSet}; -use std::fmt::Debug; +use std::fmt::{Debug, Formatter}; /// A description of a Union schema -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct UnionSchema { /// The schemas that make up this union pub(crate) schemas: Vec<Schema>, @@ -35,6 +35,15 @@ pub struct UnionSchema { variant_index: BTreeMap<SchemaKind, usize>, } +impl Debug for UnionSchema { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + // Doesn't include `variant_index` as it's a derivative of `schemas` + f.debug_struct("UnionSchema") + .field("schemas", &self.schemas) + .finish() + } +} + impl UnionSchema { /// Creates a new `UnionSchema` from a vector of schemas. /// diff --git a/avro/src/types.rs b/avro/src/types.rs index fafea3f..b3b2035 100644 --- a/avro/src/types.rs +++ b/avro/src/types.rs @@ -781,7 +781,7 @@ impl Value { fn resolve_bigdecimal(self) -> Result<Self, Error> { Ok(match self { bg @ Value::BigDecimal(_) => bg, - Value::Bytes(b) => Value::BigDecimal(deserialize_big_decimal(&b).unwrap()), + Value::Bytes(b) => Value::BigDecimal(deserialize_big_decimal(&b)?), other => return Err(Details::GetBigDecimal(other).into()), }) } @@ -1328,7 +1328,7 @@ mod tests { Value::Union(0, Box::new(Value::Null)), Schema::Union(UnionSchema::new(vec![Schema::Double, Schema::Int])?), false, - "Invalid value: Union(0, Null) for schema: Union(UnionSchema { schemas: [Double, Int], variant_index: {Int: 1, Double: 0} }). Reason: Unsupported value-schema combination! Value: Null, schema: Double", + "Invalid value: Union(0, Null) for schema: Union(UnionSchema { schemas: [Double, Int] }). Reason: Unsupported value-schema combination! Value: Null, schema: Double", ), ( Value::Union(3, Box::new(Value::Int(42))), @@ -1354,7 +1354,7 @@ mod tests { Value::Union(2, Box::new(Value::Long(1_i64))), Schema::Union(UnionSchema::new(vec![Schema::Null, Schema::Int])?), false, - "Invalid value: Union(2, Long(1)) for schema: Union(UnionSchema { schemas: [Null, Int], variant_index: {Null: 0, Int: 1} }). Reason: No schema in the union at position '2'", + "Invalid value: Union(2, Long(1)) for schema: Union(UnionSchema { schemas: [Null, Int] }). Reason: No schema in the union at position '2'", ), ( Value::Array(vec![Value::Long(42i64)]), @@ -1366,7 +1366,7 @@ mod tests { Value::Array(vec![Value::Boolean(true)]), Schema::array(Schema::Long).build(), false, - "Invalid value: Array([Boolean(true)]) for schema: Array(ArraySchema { items: Long, default: None, attributes: {} }). Reason: Unsupported value-schema combination! Value: Boolean(true), schema: Long", + "Invalid value: Array([Boolean(true)]) for schema: Array(ArraySchema { items: Long, .. }). Reason: Unsupported value-schema combination! Value: Boolean(true), schema: Long", ), ( Value::Record(vec![]), @@ -1396,12 +1396,12 @@ mod tests { attributes: BTreeMap::new(), }), false, - r#"Invalid value: Fixed(11, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for schema: Duration(FixedSchema { name: Name { name: "TestName", namespace: None }, aliases: None, doc: None, size: 12, attributes: {} }). Reason: The value's size ('11') must be exactly 12 to be a Duration"#, + r#"Invalid value: Fixed(11, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) for schema: Duration(FixedSchema { name: Name { name: "TestName", namespace: None }, size: 12, .. }). Reason: The value's size ('11') must be exactly 12 to be a Duration"#, ), ( Value::Record(vec![("unknown_field_name".to_string(), Value::Null)]), Schema::Record(RecordSchema { - name: Name::new("record_name").unwrap(), + name: Name::new("record_name")?, aliases: None, doc: None, fields: vec![RecordField { @@ -1418,12 +1418,12 @@ mod tests { attributes: Default::default(), }), false, - 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'"#, + r#"Invalid value: Record([("unknown_field_name", Null)]) for schema: Record(RecordSchema { name: Name { name: "record_name", namespace: None }, fields: [RecordField { name: "field_name", schema: Int, position: 0, .. }], .. }). Reason: There is no schema field for field 'unknown_field_name'"#, ), ( Value::Record(vec![("field_name".to_string(), Value::Null)]), Schema::Record(RecordSchema { - name: Name::new("record_name").unwrap(), + name: Name::new("record_name")?, aliases: None, doc: None, fields: vec![RecordField { @@ -1432,7 +1432,7 @@ mod tests { default: None, aliases: None, schema: Schema::Ref { - name: Name::new("missing").unwrap(), + name: Name::new("missing")?, }, order: RecordFieldOrder::Ignore, position: 0, @@ -1442,7 +1442,7 @@ mod tests { attributes: Default::default(), }), false, - 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 [...] + r#"Invalid value: Record([("field_name", Null)]) for schema: Record(RecordSchema { name: Name { name: "record_name", namespace: None }, fields: [RecordField { name: "field_name", schema: Ref { name: Name { name: "missing", namespace: None } }, position: 0, .. }], .. }). Reason: Unresolved schema reference: 'Name { name: "missing", namespace: None }'. Parsed names: []"#, ), ]; @@ -1468,7 +1468,7 @@ mod tests { fn validate_fixed() -> TestResult { let schema = Schema::Fixed(FixedSchema { size: 4, - name: Name::new("some_fixed").unwrap(), + name: Name::new("some_fixed")?, aliases: None, doc: None, attributes: Default::default(), @@ -1502,7 +1502,7 @@ mod tests { #[test] fn validate_enum() -> TestResult { let schema = Schema::Enum(EnumSchema { - name: Name::new("some_enum").unwrap(), + name: Name::new("some_enum")?, aliases: None, doc: None, symbols: vec![ @@ -1549,7 +1549,7 @@ mod tests { ); let other_schema = Schema::Enum(EnumSchema { - name: Name::new("some_other_enum").unwrap(), + name: Name::new("some_other_enum")?, aliases: None, doc: None, symbols: vec![ @@ -1590,7 +1590,7 @@ mod tests { // ] // } let schema = Schema::Record(RecordSchema { - name: Name::new("some_record").unwrap(), + name: Name::new("some_record")?, aliases: None, doc: None, fields: vec![ @@ -1656,7 +1656,7 @@ mod tests { ]); assert!(!value.validate(&schema)); assert_logged( - 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 [...] + r#"Invalid value: Record([("a", Boolean(false)), ("b", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, fields: [RecordField { name: "a", schema: Long, position: 0, .. }, RecordField { name: "b", schema: String, position: 1, .. }, RecordField { name: "c", default: Null, schema: Union(UnionSchema { schemas: [Null, Int] }), position: 2, .. }], .. }). Reason: Unsupported value-schema combination! Value: Boolean(false), schem [...] ); let value = Value::Record(vec![ @@ -1665,7 +1665,7 @@ mod tests { ]); assert!(!value.validate(&schema)); assert_logged( - 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 [...] + r#"Invalid value: Record([("a", Long(42)), ("c", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, fields: [RecordField { name: "a", schema: Long, position: 0, .. }, RecordField { name: "b", schema: String, position: 1, .. }, RecordField { name: "c", default: Null, schema: Union(UnionSchema { schemas: [Null, Int] }), position: 2, .. }], .. }). Reason: Could not find matching type in union"#, ); assert_not_logged( r#"Invalid value: String("foo") for schema: Int. Reason: Unsupported value-schema combination"#, @@ -1677,7 +1677,7 @@ mod tests { ]); assert!(!value.validate(&schema)); assert_logged( - 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 [...] + r#"Invalid value: Record([("a", Long(42)), ("d", String("foo"))]) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, fields: [RecordField { name: "a", schema: Long, position: 0, .. }, RecordField { name: "b", schema: String, position: 1, .. }, RecordField { name: "c", default: Null, schema: Union(UnionSchema { schemas: [Null, Int] }), position: 2, .. }], .. }). Reason: There is no schema field for field 'd'"#, ); let value = Value::Record(vec![ @@ -1688,7 +1688,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(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 [...] + 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 }, fields: [RecordField { name: "a", schema: Long, position: 0, .. }, RecordField { name: "b", schema: String, position: 1, .. }, RecordField { name: "c", default: Null, schema: Union(UnionSchema { schemas: [Null, Int] }), position: 2, .. }], .. }). Reason: The value's records length (4) is greater than [...] ); assert!( @@ -1712,7 +1712,7 @@ mod tests { .validate(&schema) ); assert_logged( - 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: [...] + r#"Invalid value: Map({"d": Long(123)}) for schema: Record(RecordSchema { name: Name { name: "some_record", namespace: None }, fields: [RecordField { name: "a", schema: Long, position: 0, .. }, RecordField { name: "b", schema: String, position: 1, .. }, RecordField { name: "c", default: Null, schema: Union(UnionSchema { schemas: [Null, Int] }), position: 2, .. }], .. }). Reason: Field with name '"a"' is not a member of the map items Field with name '"b"' is not a member of the map items"#, ); diff --git a/avro/src/writer.rs b/avro/src/writer.rs index 2ccfca3..3031236 100644 --- a/avro/src/writer.rs +++ b/avro/src/writer.rs @@ -1785,7 +1785,7 @@ mod tests { Err(e) => { assert_eq!( e.to_string(), - r#"Failed to serialize field 'time' for record Record(RecordSchema { name: Name { name: "Conference", namespace: None }, aliases: None, doc: None, fields: [RecordField { name: "name", doc: None, aliases: None, default: None, schema: String, order: Ascending, position: 0, custom_attributes: {} }, RecordField { name: "date", doc: None, aliases: Some(["time2", "time"]), default: None, schema: Union(UnionSchema { schemas: [Null, Long], variant_index: {Null: 0, Long: 1} }) [...] + r#"Failed to serialize field 'time' for record Record(RecordSchema { name: Name { name: "Conference", namespace: None }, fields: [RecordField { name: "name", schema: String, position: 0, .. }, RecordField { name: "date", aliases: ["time2", "time"], schema: Union(UnionSchema { schemas: [Null, Long] }), position: 1, .. }], .. }): Failed to serialize value of type f64 using schema Union(UnionSchema { schemas: [Null, Long] }): 12345678.9. Cause: Cannot find a Double schem [...] ); } } diff --git a/avro/tests/serde_human_readable_true.rs b/avro/tests/serde_human_readable_true.rs index ca7a58b..c71a91e 100644 --- a/avro/tests/serde_human_readable_true.rs +++ b/avro/tests/serde_human_readable_true.rs @@ -103,7 +103,7 @@ fn avro_rs_440_uuid_bytes() -> TestResult { let writer = SpecificSingleObjectWriter::new()?; assert_eq!( writer.write(uuid, &mut buffer).unwrap_err().to_string(), - "Failed to serialize value of type string using schema Uuid(Bytes): 550e8400-e29b-41d4-a716-446655440000. Cause: Expected bytes but got a string. Did you mean to use `Schema::Uuid(UuidSchema::String)` or `utils::serde_set_human_readable(false)`?" + r#"Failed to serialize value of type string using schema Uuid(Bytes): 550e8400-e29b-41d4-a716-446655440000. Cause: Expected bytes but got a string. Did you mean to use `Schema::Uuid(UuidSchema::String)` or `utils::serde_set_human_readable(false)`?"# ); Ok(()) @@ -129,7 +129,7 @@ fn avro_rs_440_uuid_fixed() -> TestResult { let writer = SpecificSingleObjectWriter::new()?; assert_eq!( writer.write(uuid, &mut buffer).unwrap_err().to_string(), - r#"Failed to serialize value of type string using schema Uuid(Fixed(FixedSchema { name: Name { name: "uuid", namespace: None }, aliases: None, doc: None, size: 16, attributes: {} })): 550e8400-e29b-41d4-a716-446655440000. Cause: Expected bytes but got a string. Did you mean to use `Schema::Uuid(UuidSchema::String)` or `utils::serde_set_human_readable(false)`?"# + r#"Failed to serialize value of type string using schema Uuid(Fixed(FixedSchema { name: Name { name: "uuid", namespace: None }, size: 16, .. })): 550e8400-e29b-41d4-a716-446655440000. Cause: Expected bytes but got a string. Did you mean to use `Schema::Uuid(UuidSchema::String)` or `utils::serde_set_human_readable(false)`?"# ); Ok(())
