1use crate::schema::{InnerDecimalSchema, UuidSchema};
53use crate::{
54 Schema,
55 schema::{
56 ArraySchema, DecimalSchema, EnumSchema, FixedSchema, MapSchema, RecordField, RecordSchema,
57 UnionSchema,
58 },
59};
60use log::debug;
61use std::{fmt::Debug, sync::OnceLock};
62
63pub trait SchemataEq: Debug + Send + Sync {
67 fn compare(&self, schema_one: &Schema, schema_two: &Schema) -> bool;
69}
70
71#[derive(Debug)]
75pub struct SpecificationEq;
76impl SchemataEq for SpecificationEq {
77 fn compare(&self, schema_one: &Schema, schema_two: &Schema) -> bool {
78 schema_one.canonical_form() == schema_two.canonical_form()
79 }
80}
81
82#[derive(Debug)]
88pub struct StructFieldEq {
89 pub include_attributes: bool,
93}
94
95impl SchemataEq for StructFieldEq {
96 #[rustfmt::skip]
97 fn compare(&self, schema_one: &Schema, schema_two: &Schema) -> bool {
98 if schema_one.name() != schema_two.name() {
99 return false;
100 }
101
102 if self.include_attributes
103 && schema_one.custom_attributes() != schema_two.custom_attributes()
104 {
105 return false;
106 }
107
108 match (schema_one, schema_two) {
109 (Schema::Null, Schema::Null) => true,
110 (Schema::Null, _) => false,
111 (Schema::Boolean, Schema::Boolean) => true,
112 (Schema::Boolean, _) => false,
113 (Schema::Int, Schema::Int) => true,
114 (Schema::Int, _) => false,
115 (Schema::Long, Schema::Long) => true,
116 (Schema::Long, _) => false,
117 (Schema::Float, Schema::Float) => true,
118 (Schema::Float, _) => false,
119 (Schema::Double, Schema::Double) => true,
120 (Schema::Double, _) => false,
121 (Schema::Bytes, Schema::Bytes) => true,
122 (Schema::Bytes, _) => false,
123 (Schema::String, Schema::String) => true,
124 (Schema::String, _) => false,
125 (Schema::BigDecimal, Schema::BigDecimal) => true,
126 (Schema::BigDecimal, _) => false,
127 (Schema::Date, Schema::Date) => true,
128 (Schema::Date, _) => false,
129 (Schema::TimeMicros, Schema::TimeMicros) => true,
130 (Schema::TimeMicros, _) => false,
131 (Schema::TimeMillis, Schema::TimeMillis) => true,
132 (Schema::TimeMillis, _) => false,
133 (Schema::TimestampMicros, Schema::TimestampMicros) => true,
134 (Schema::TimestampMicros, _) => false,
135 (Schema::TimestampMillis, Schema::TimestampMillis) => true,
136 (Schema::TimestampMillis, _) => false,
137 (Schema::TimestampNanos, Schema::TimestampNanos) => true,
138 (Schema::TimestampNanos, _) => false,
139 (Schema::LocalTimestampMicros, Schema::LocalTimestampMicros) => true,
140 (Schema::LocalTimestampMicros, _) => false,
141 (Schema::LocalTimestampMillis, Schema::LocalTimestampMillis) => true,
142 (Schema::LocalTimestampMillis, _) => false,
143 (Schema::LocalTimestampNanos, Schema::LocalTimestampNanos) => true,
144 (Schema::LocalTimestampNanos, _) => false,
145 (
146 Schema::Record(RecordSchema { fields: fields_one, ..}),
147 Schema::Record(RecordSchema { fields: fields_two, ..})
148 ) => {
149 self.compare_fields(fields_one, fields_two)
150 }
151 (Schema::Record(_), _) => false,
152 (
153 Schema::Enum(EnumSchema { symbols: symbols_one, ..}),
154 Schema::Enum(EnumSchema { symbols: symbols_two, .. })
155 ) => {
156 symbols_one == symbols_two
157 }
158 (Schema::Enum(_), _) => false,
159 (
160 Schema::Fixed(FixedSchema { size: size_one, ..}),
161 Schema::Fixed(FixedSchema { size: size_two, .. })
162 ) => {
163 size_one == size_two
164 }
165 (Schema::Fixed(_), _) => false,
166 (
167 Schema::Union(UnionSchema { schemas: schemas_one, ..}),
168 Schema::Union(UnionSchema { schemas: schemas_two, .. })
169 ) => {
170 schemas_one.len() == schemas_two.len()
171 && schemas_one
172 .iter()
173 .zip(schemas_two.iter())
174 .all(|(s1, s2)| self.compare(s1, s2))
175 }
176 (Schema::Union(_), _) => false,
177 (
178 Schema::Decimal(DecimalSchema { precision: precision_one, scale: scale_one, inner: inner_one }),
179 Schema::Decimal(DecimalSchema { precision: precision_two, scale: scale_two, inner: inner_two })
180 ) => {
181 precision_one == precision_two && scale_one == scale_two && match (inner_one, inner_two) {
182 (InnerDecimalSchema::Bytes, InnerDecimalSchema::Bytes) => true,
183 (InnerDecimalSchema::Fixed(FixedSchema { size: size_one, .. }), InnerDecimalSchema::Fixed(FixedSchema { size: size_two, ..})) => {
184 size_one == size_two
185 }
186 _ => false,
187 }
188 }
189 (Schema::Decimal(_), _) => false,
190 (Schema::Uuid(UuidSchema::Bytes), Schema::Uuid(UuidSchema::Bytes)) => true,
191 (Schema::Uuid(UuidSchema::Bytes), _) => false,
192 (Schema::Uuid(UuidSchema::String), Schema::Uuid(UuidSchema::String)) => true,
193 (Schema::Uuid(UuidSchema::String), _) => false,
194 (Schema::Uuid(UuidSchema::Fixed(FixedSchema { size: size_one, ..})), Schema::Uuid(UuidSchema::Fixed(FixedSchema { size: size_two, ..}))) => {
195 size_one == size_two
196 },
197 (Schema::Uuid(UuidSchema::Fixed(_)), _) => false,
198 (
199 Schema::Array(ArraySchema { items: items_one, ..}),
200 Schema::Array(ArraySchema { items: items_two, ..})
201 ) => {
202 self.compare(items_one, items_two)
203 }
204 (Schema::Array(_), _) => false,
205 (Schema::Duration(FixedSchema { size: size_one, ..}), Schema::Duration(FixedSchema { size: size_two, ..})) => size_one == size_two,
206 (Schema::Duration(_), _) => false,
207 (
208 Schema::Map(MapSchema { types: types_one, ..}),
209 Schema::Map(MapSchema { types: types_two, ..})
210 ) => {
211 self.compare(types_one, types_two)
212 }
213 (Schema::Map(_), _) => false,
214 (
215 Schema::Ref { name: name_one },
216 Schema::Ref { name: name_two }
217 ) => {
218 name_one == name_two
219 }
220 (Schema::Ref { .. }, _) => false,
221 }
222 }
223}
224
225impl StructFieldEq {
226 fn compare_fields(&self, fields_one: &[RecordField], fields_two: &[RecordField]) -> bool {
227 fields_one.len() == fields_two.len()
228 && fields_one
229 .iter()
230 .zip(fields_two.iter())
231 .all(|(f1, f2)| f1.name == f2.name && self.compare(&f1.schema, &f2.schema))
232 }
233}
234
235static SCHEMATA_COMPARATOR_ONCE: OnceLock<Box<dyn SchemataEq>> = OnceLock::new();
236
237pub fn set_schemata_equality_comparator(
245 comparator: Box<dyn SchemataEq>,
246) -> Result<(), Box<dyn SchemataEq>> {
247 debug!("Setting a custom schemata equality comparator: {comparator:?}.");
248 SCHEMATA_COMPARATOR_ONCE.set(comparator)
249}
250
251pub(crate) fn compare_schemata(schema_one: &Schema, schema_two: &Schema) -> bool {
252 SCHEMATA_COMPARATOR_ONCE
253 .get_or_init(|| {
254 debug!("Going to use the default schemata equality comparator: StructFieldEq.",);
255 Box::new(StructFieldEq {
256 include_attributes: false,
257 })
258 })
259 .compare(schema_one, schema_two)
260}
261
262#[cfg(test)]
263#[allow(non_snake_case)]
264mod tests {
265 use super::*;
266 use crate::schema::{InnerDecimalSchema, Name};
267 use apache_avro_test_helper::TestResult;
268 use serde_json::Value;
269 use std::collections::BTreeMap;
270 use std::num::NonZero;
271
272 const SPECIFICATION_EQ: SpecificationEq = SpecificationEq;
273 const STRUCT_FIELD_EQ: StructFieldEq = StructFieldEq {
274 include_attributes: false,
275 };
276 const STRUCT_FIELD_EQ_WITH_ATTRS: StructFieldEq = StructFieldEq {
277 include_attributes: true,
278 };
279
280 macro_rules! test_primitives {
281 ($primitive:ident) => {
282 paste::item! {
283 #[test]
284 fn [<test_avro_3939_compare_schemata_$primitive>]() {
285 let specification_eq_res = SPECIFICATION_EQ.compare(&Schema::$primitive, &Schema::$primitive);
286 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&Schema::$primitive, &Schema::$primitive);
287 assert_eq!(specification_eq_res, struct_field_eq_res)
288 }
289 }
290 };
291 }
292
293 test_primitives!(Null);
294 test_primitives!(Boolean);
295 test_primitives!(Int);
296 test_primitives!(Long);
297 test_primitives!(Float);
298 test_primitives!(Double);
299 test_primitives!(Bytes);
300 test_primitives!(String);
301 test_primitives!(BigDecimal);
302 test_primitives!(Date);
303 test_primitives!(TimeMicros);
304 test_primitives!(TimeMillis);
305 test_primitives!(TimestampMicros);
306 test_primitives!(TimestampMillis);
307 test_primitives!(TimestampNanos);
308 test_primitives!(LocalTimestampMicros);
309 test_primitives!(LocalTimestampMillis);
310 test_primitives!(LocalTimestampNanos);
311
312 #[test]
313 fn avro_rs_382_compare_schemata_duration_equal() {
314 let schema_one = Schema::Duration(FixedSchema {
315 name: Name::try_from("name1").expect("Name is valid"),
316 size: 12,
317 aliases: None,
318 doc: None,
319 attributes: BTreeMap::new(),
320 });
321 let schema_two = Schema::Duration(FixedSchema {
322 name: Name::try_from("name1").expect("Name is valid"),
323 size: 12,
324 aliases: None,
325 doc: None,
326 attributes: BTreeMap::new(),
327 });
328 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
329 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
330 assert_eq!(specification_eq_res, struct_field_eq_res);
331 }
332
333 #[test]
334 fn avro_rs_382_compare_schemata_duration_different_names() {
335 let schema_one = Schema::Duration(FixedSchema {
336 name: Name::try_from("name1").expect("Name is valid"),
337 size: 12,
338 aliases: None,
339 doc: None,
340 attributes: BTreeMap::new(),
341 });
342 let schema_two = Schema::Duration(FixedSchema {
343 name: Name::try_from("name2").expect("Name is valid"),
344 size: 12,
345 aliases: None,
346 doc: None,
347 attributes: BTreeMap::new(),
348 });
349 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
350 assert!(!specification_eq_res);
351
352 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
353 assert!(!struct_field_eq_res);
354 }
355
356 #[test]
357 fn avro_rs_382_compare_schemata_duration_different_attributes() {
358 let schema_one = Schema::Duration(FixedSchema {
359 name: Name::try_from("name1").expect("Name is valid"),
360 size: 12,
361 aliases: None,
362 doc: None,
363 attributes: vec![(String::from("attr1"), serde_json::Value::Bool(true))]
364 .into_iter()
365 .collect(),
366 });
367 let schema_two = Schema::Duration(FixedSchema {
368 name: Name::try_from("name1").expect("Name is valid"),
369 size: 12,
370 aliases: None,
371 doc: None,
372 attributes: BTreeMap::new(),
373 });
374 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
375 assert!(specification_eq_res);
376
377 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
378 assert!(struct_field_eq_res);
379
380 let struct_field_eq_with_attrs_res =
381 STRUCT_FIELD_EQ_WITH_ATTRS.compare(&schema_one, &schema_two);
382 assert!(!struct_field_eq_with_attrs_res);
383 }
384
385 #[test]
386 fn avro_rs_382_compare_schemata_duration_different_sizes() {
387 let schema_one = Schema::Duration(FixedSchema {
388 name: Name::try_from("name1").expect("Name is valid"),
389 size: 8,
390 aliases: None,
391 doc: None,
392 attributes: BTreeMap::new(),
393 });
394 let schema_two = Schema::Duration(FixedSchema {
395 name: Name::try_from("name1").expect("Name is valid"),
396 size: 12,
397 aliases: None,
398 doc: None,
399 attributes: BTreeMap::new(),
400 });
401 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
402 assert!(!specification_eq_res);
403
404 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
405 assert!(!struct_field_eq_res);
406 }
407
408 #[test]
409 fn test_avro_3939_compare_named_schemata_with_different_names() {
410 let schema_one = Schema::Ref {
411 name: Name::try_from("name1").expect("Name is valid"),
412 };
413
414 let schema_two = Schema::Ref {
415 name: Name::try_from("name2").expect("Name is valid"),
416 };
417
418 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
419 assert!(!specification_eq_res);
420 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
421 assert!(!struct_field_eq_res);
422
423 assert_eq!(specification_eq_res, struct_field_eq_res);
424 }
425
426 #[test]
427 fn test_avro_3939_compare_schemata_not_including_attributes() {
428 let schema_one = Schema::map(Schema::Boolean)
429 .attributes(BTreeMap::from_iter([(
430 "key1".to_string(),
431 Value::Bool(true),
432 )]))
433 .build();
434 let schema_two = Schema::map(Schema::Boolean)
435 .attributes(BTreeMap::from_iter([(
436 "key2".to_string(),
437 Value::Bool(true),
438 )]))
439 .build();
440 assert!(STRUCT_FIELD_EQ.compare(&schema_one, &schema_two));
442 }
443
444 #[test]
445 fn test_avro_3939_compare_schemata_including_attributes() {
446 let struct_field_eq = StructFieldEq {
447 include_attributes: true,
448 };
449 let schema_one = Schema::map(Schema::Boolean)
450 .attributes(BTreeMap::from_iter([(
451 "key1".to_string(),
452 Value::Bool(true),
453 )]))
454 .build();
455 let schema_two = Schema::map(Schema::Boolean)
456 .attributes(BTreeMap::from_iter([(
457 "key2".to_string(),
458 Value::Bool(true),
459 )]))
460 .build();
461 assert!(!struct_field_eq.compare(&schema_one, &schema_two));
462 }
463
464 #[test]
465 fn test_avro_3939_compare_map_schemata() {
466 let schema_one = Schema::map(Schema::Boolean).build();
467 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
468 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
469
470 let schema_two = Schema::map(Schema::Boolean).build();
471
472 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
473 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
474 assert!(
475 specification_eq_res,
476 "SpecificationEq: Equality of two Schema::Map failed!"
477 );
478 assert!(
479 struct_field_eq_res,
480 "StructFieldEq: Equality of two Schema::Map failed!"
481 );
482 assert_eq!(specification_eq_res, struct_field_eq_res);
483 }
484
485 #[test]
486 fn test_avro_3939_compare_array_schemata() {
487 let schema_one = Schema::array(Schema::Boolean).build();
488 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
489 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
490
491 let schema_two = Schema::array(Schema::Boolean).build();
492
493 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
494 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
495 assert!(
496 specification_eq_res,
497 "SpecificationEq: Equality of two Schema::Array failed!"
498 );
499 assert!(
500 struct_field_eq_res,
501 "StructFieldEq: Equality of two Schema::Array failed!"
502 );
503 assert_eq!(specification_eq_res, struct_field_eq_res);
504 }
505
506 #[test]
507 fn test_avro_3939_compare_decimal_schemata() {
508 let schema_one = Schema::Decimal(DecimalSchema {
509 precision: NonZero::new(10).unwrap(),
510 scale: 2,
511 inner: InnerDecimalSchema::Bytes,
512 });
513 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
514 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
515
516 let schema_two = Schema::Decimal(DecimalSchema {
517 precision: NonZero::new(10).unwrap(),
518 scale: 2,
519 inner: InnerDecimalSchema::Bytes,
520 });
521
522 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
523 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
524 assert!(
525 specification_eq_res,
526 "SpecificationEq: Equality of two Schema::Decimal failed!"
527 );
528 assert!(
529 struct_field_eq_res,
530 "StructFieldEq: Equality of two Schema::Decimal failed!"
531 );
532 assert_eq!(specification_eq_res, struct_field_eq_res);
533 }
534
535 #[test]
536 fn test_avro_3939_compare_fixed_schemata() {
537 let schema_one = Schema::Fixed(FixedSchema {
538 name: Name::try_from("fixed").expect("Name is valid"),
539 doc: None,
540 size: 10,
541 aliases: None,
542 attributes: BTreeMap::new(),
543 });
544 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
545 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
546
547 let schema_two = Schema::Fixed(FixedSchema {
548 name: Name::try_from("fixed").expect("Name is valid"),
549 doc: None,
550 size: 10,
551 aliases: None,
552 attributes: BTreeMap::new(),
553 });
554
555 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
556 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
557 assert!(
558 specification_eq_res,
559 "SpecificationEq: Equality of two Schema::Fixed failed!"
560 );
561 assert!(
562 struct_field_eq_res,
563 "StructFieldEq: Equality of two Schema::Fixed failed!"
564 );
565 assert_eq!(specification_eq_res, struct_field_eq_res);
566 }
567
568 #[test]
569 fn test_avro_3939_compare_enum_schemata() {
570 let schema_one = Schema::Enum(EnumSchema {
571 name: Name::try_from("enum").expect("Name is valid"),
572 doc: None,
573 symbols: vec!["A".to_string(), "B".to_string()],
574 default: None,
575 aliases: None,
576 attributes: BTreeMap::new(),
577 });
578 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
579 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
580
581 let schema_two = Schema::Enum(EnumSchema {
582 name: Name::try_from("enum").expect("Name is valid"),
583 doc: None,
584 symbols: vec!["A".to_string(), "B".to_string()],
585 default: None,
586 aliases: None,
587 attributes: BTreeMap::new(),
588 });
589
590 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
591 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
592 assert!(
593 specification_eq_res,
594 "SpecificationEq: Equality of two Schema::Enum failed!"
595 );
596 assert!(
597 struct_field_eq_res,
598 "StructFieldEq: Equality of two Schema::Enum failed!"
599 );
600 assert_eq!(specification_eq_res, struct_field_eq_res);
601 }
602
603 #[test]
604 fn test_avro_3939_compare_ref_schemata() {
605 let schema_one = Schema::Ref {
606 name: Name::try_from("ref").expect("Name is valid"),
607 };
608 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
609 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
610
611 let schema_two = Schema::Ref {
612 name: Name::try_from("ref").expect("Name is valid"),
613 };
614
615 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
616 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
617 assert!(
618 specification_eq_res,
619 "SpecificationEq: Equality of two Schema::Ref failed!"
620 );
621 assert!(
622 struct_field_eq_res,
623 "StructFieldEq: Equality of two Schema::Ref failed!"
624 );
625 assert_eq!(specification_eq_res, struct_field_eq_res);
626 }
627
628 #[test]
629 fn test_avro_3939_compare_record_schemata() {
630 let schema_one = Schema::Record(RecordSchema {
631 name: Name::try_from("record").expect("Name is valid"),
632 doc: None,
633 fields: vec![
634 RecordField::builder()
635 .name("field".to_string())
636 .schema(Schema::Boolean)
637 .build(),
638 ],
639 aliases: None,
640 attributes: BTreeMap::new(),
641 lookup: Default::default(),
642 });
643 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
644 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
645
646 let schema_two = Schema::Record(RecordSchema {
647 name: Name::try_from("record").expect("Name is valid"),
648 doc: None,
649 fields: vec![
650 RecordField::builder()
651 .name("field".to_string())
652 .schema(Schema::Boolean)
653 .build(),
654 ],
655 aliases: None,
656 attributes: BTreeMap::new(),
657 lookup: Default::default(),
658 });
659
660 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
661 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
662 assert!(
663 specification_eq_res,
664 "SpecificationEq: Equality of two Schema::Record failed!"
665 );
666 assert!(
667 struct_field_eq_res,
668 "StructFieldEq: Equality of two Schema::Record failed!"
669 );
670 assert_eq!(specification_eq_res, struct_field_eq_res);
671 }
672
673 #[test]
674 fn test_avro_3939_compare_union_schemata() -> TestResult {
675 let schema_one = Schema::Union(UnionSchema::new(vec![Schema::Boolean, Schema::Int])?);
676 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
677 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
678
679 let schema_two = Schema::Union(UnionSchema::new(vec![Schema::Boolean, Schema::Int])?);
680
681 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
682 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
683 assert!(
684 specification_eq_res,
685 "SpecificationEq: Equality of two Schema::Union failed!"
686 );
687 assert!(
688 struct_field_eq_res,
689 "StructFieldEq: Equality of two Schema::Union failed!"
690 );
691 assert_eq!(specification_eq_res, struct_field_eq_res);
692 Ok(())
693 }
694
695 #[test]
696 fn test_uuid_compare_uuid() -> TestResult {
697 let string = Schema::Uuid(UuidSchema::String);
698 let bytes = Schema::Uuid(UuidSchema::Bytes);
699 let mut fixed_schema = FixedSchema {
700 name: Name::new("some_name")?,
701 aliases: None,
702 doc: None,
703 size: 16,
704 attributes: Default::default(),
705 };
706 let fixed = Schema::Uuid(UuidSchema::Fixed(fixed_schema.clone()));
707 fixed_schema
708 .attributes
709 .insert("Something".to_string(), Value::Null);
710 let fixed_different = Schema::Uuid(UuidSchema::Fixed(fixed_schema));
711
712 assert!(SPECIFICATION_EQ.compare(&string, &string));
713 assert!(STRUCT_FIELD_EQ.compare(&string, &string));
714 assert!(SPECIFICATION_EQ.compare(&bytes, &bytes));
715 assert!(STRUCT_FIELD_EQ.compare(&bytes, &bytes));
716 assert!(SPECIFICATION_EQ.compare(&fixed, &fixed));
717 assert!(STRUCT_FIELD_EQ.compare(&fixed, &fixed));
718
719 assert!(!SPECIFICATION_EQ.compare(&string, &bytes));
720 assert!(!STRUCT_FIELD_EQ.compare(&string, &bytes));
721 assert!(!SPECIFICATION_EQ.compare(&bytes, &string));
722 assert!(!STRUCT_FIELD_EQ.compare(&bytes, &string));
723 assert!(!SPECIFICATION_EQ.compare(&string, &fixed));
724 assert!(!STRUCT_FIELD_EQ.compare(&string, &fixed));
725 assert!(!SPECIFICATION_EQ.compare(&fixed, &string));
726 assert!(!STRUCT_FIELD_EQ.compare(&fixed, &string));
727 assert!(!SPECIFICATION_EQ.compare(&bytes, &fixed));
728 assert!(!STRUCT_FIELD_EQ.compare(&bytes, &fixed));
729 assert!(!SPECIFICATION_EQ.compare(&fixed, &bytes));
730 assert!(!STRUCT_FIELD_EQ.compare(&fixed, &bytes));
731
732 assert!(SPECIFICATION_EQ.compare(&fixed, &fixed_different));
733 assert!(STRUCT_FIELD_EQ.compare(&fixed, &fixed_different));
734 assert!(SPECIFICATION_EQ.compare(&fixed_different, &fixed));
735 assert!(STRUCT_FIELD_EQ.compare(&fixed_different, &fixed));
736
737 let strict = StructFieldEq {
738 include_attributes: true,
739 };
740
741 assert!(!strict.compare(&fixed, &fixed_different));
742 assert!(!strict.compare(&fixed_different, &fixed));
743
744 Ok(())
745 }
746}