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, RecordFieldOrder};
267 use apache_avro_test_helper::TestResult;
268 use serde_json::Value;
269 use std::collections::BTreeMap;
270
271 const SPECIFICATION_EQ: SpecificationEq = SpecificationEq;
272 const STRUCT_FIELD_EQ: StructFieldEq = StructFieldEq {
273 include_attributes: false,
274 };
275 const STRUCT_FIELD_EQ_WITH_ATTRS: StructFieldEq = StructFieldEq {
276 include_attributes: true,
277 };
278
279 macro_rules! test_primitives {
280 ($primitive:ident) => {
281 paste::item! {
282 #[test]
283 fn [<test_avro_3939_compare_schemata_$primitive>]() {
284 let specification_eq_res = SPECIFICATION_EQ.compare(&Schema::$primitive, &Schema::$primitive);
285 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&Schema::$primitive, &Schema::$primitive);
286 assert_eq!(specification_eq_res, struct_field_eq_res)
287 }
288 }
289 };
290 }
291
292 test_primitives!(Null);
293 test_primitives!(Boolean);
294 test_primitives!(Int);
295 test_primitives!(Long);
296 test_primitives!(Float);
297 test_primitives!(Double);
298 test_primitives!(Bytes);
299 test_primitives!(String);
300 test_primitives!(BigDecimal);
301 test_primitives!(Date);
302 test_primitives!(TimeMicros);
303 test_primitives!(TimeMillis);
304 test_primitives!(TimestampMicros);
305 test_primitives!(TimestampMillis);
306 test_primitives!(TimestampNanos);
307 test_primitives!(LocalTimestampMicros);
308 test_primitives!(LocalTimestampMillis);
309 test_primitives!(LocalTimestampNanos);
310
311 #[test]
312 fn avro_rs_382_compare_schemata_duration_equal() {
313 let schema_one = Schema::Duration(FixedSchema {
314 name: Name::try_from("name1").expect("Name is valid"),
315 size: 12,
316 aliases: None,
317 doc: None,
318 attributes: BTreeMap::new(),
319 });
320 let schema_two = Schema::Duration(FixedSchema {
321 name: Name::try_from("name1").expect("Name is valid"),
322 size: 12,
323 aliases: None,
324 doc: None,
325 attributes: BTreeMap::new(),
326 });
327 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
328 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
329 assert_eq!(specification_eq_res, struct_field_eq_res)
330 }
331
332 #[test]
333 fn avro_rs_382_compare_schemata_duration_different_names() {
334 let schema_one = Schema::Duration(FixedSchema {
335 name: Name::try_from("name1").expect("Name is valid"),
336 size: 12,
337 aliases: None,
338 doc: None,
339 attributes: BTreeMap::new(),
340 });
341 let schema_two = Schema::Duration(FixedSchema {
342 name: Name::try_from("name2").expect("Name is valid"),
343 size: 12,
344 aliases: None,
345 doc: None,
346 attributes: BTreeMap::new(),
347 });
348 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
349 assert!(!specification_eq_res);
350
351 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
352 assert!(!struct_field_eq_res)
353 }
354
355 #[test]
356 fn avro_rs_382_compare_schemata_duration_different_attributes() {
357 let schema_one = Schema::Duration(FixedSchema {
358 name: Name::try_from("name1").expect("Name is valid"),
359 size: 12,
360 aliases: None,
361 doc: None,
362 attributes: vec![(String::from("attr1"), serde_json::Value::Bool(true))]
363 .into_iter()
364 .collect(),
365 });
366 let schema_two = Schema::Duration(FixedSchema {
367 name: Name::try_from("name1").expect("Name is valid"),
368 size: 12,
369 aliases: None,
370 doc: None,
371 attributes: BTreeMap::new(),
372 });
373 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
374 assert!(specification_eq_res);
375
376 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
377 assert!(struct_field_eq_res);
378
379 let struct_field_eq_with_attrs_res =
380 STRUCT_FIELD_EQ_WITH_ATTRS.compare(&schema_one, &schema_two);
381 assert!(!struct_field_eq_with_attrs_res);
382 }
383
384 #[test]
385 fn avro_rs_382_compare_schemata_duration_different_sizes() {
386 let schema_one = Schema::Duration(FixedSchema {
387 name: Name::try_from("name1").expect("Name is valid"),
388 size: 8,
389 aliases: None,
390 doc: None,
391 attributes: BTreeMap::new(),
392 });
393 let schema_two = Schema::Duration(FixedSchema {
394 name: Name::try_from("name1").expect("Name is valid"),
395 size: 12,
396 aliases: None,
397 doc: None,
398 attributes: BTreeMap::new(),
399 });
400 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
401 assert!(!specification_eq_res);
402
403 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
404 assert!(!struct_field_eq_res);
405 }
406
407 #[test]
408 fn test_avro_3939_compare_named_schemata_with_different_names() {
409 let schema_one = Schema::Ref {
410 name: Name::try_from("name1").expect("Name is valid"),
411 };
412
413 let schema_two = Schema::Ref {
414 name: Name::try_from("name2").expect("Name is valid"),
415 };
416
417 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
418 assert!(!specification_eq_res);
419 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
420 assert!(!struct_field_eq_res);
421
422 assert_eq!(specification_eq_res, struct_field_eq_res);
423 }
424
425 #[test]
426 fn test_avro_3939_compare_schemata_not_including_attributes() {
427 let schema_one = Schema::map_with_attributes(
428 Schema::Boolean,
429 BTreeMap::from_iter([("key1".to_string(), Value::Bool(true))]),
430 );
431 let schema_two = Schema::map_with_attributes(
432 Schema::Boolean,
433 BTreeMap::from_iter([("key2".to_string(), Value::Bool(true))]),
434 );
435 assert!(STRUCT_FIELD_EQ.compare(&schema_one, &schema_two));
437 }
438
439 #[test]
440 fn test_avro_3939_compare_schemata_including_attributes() {
441 let struct_field_eq = StructFieldEq {
442 include_attributes: true,
443 };
444 let schema_one = Schema::map_with_attributes(
445 Schema::Boolean,
446 BTreeMap::from_iter([("key1".to_string(), Value::Bool(true))]),
447 );
448 let schema_two = Schema::map_with_attributes(
449 Schema::Boolean,
450 BTreeMap::from_iter([("key2".to_string(), Value::Bool(true))]),
451 );
452 assert!(!struct_field_eq.compare(&schema_one, &schema_two));
453 }
454
455 #[test]
456 fn test_avro_3939_compare_map_schemata() {
457 let schema_one = Schema::map(Schema::Boolean);
458 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
459 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
460
461 let schema_two = Schema::map(Schema::Boolean);
462
463 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
464 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
465 assert!(
466 specification_eq_res,
467 "SpecificationEq: Equality of two Schema::Map failed!"
468 );
469 assert!(
470 struct_field_eq_res,
471 "StructFieldEq: Equality of two Schema::Map failed!"
472 );
473 assert_eq!(specification_eq_res, struct_field_eq_res);
474 }
475
476 #[test]
477 fn test_avro_3939_compare_array_schemata() {
478 let schema_one = Schema::array(Schema::Boolean);
479 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
480 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
481
482 let schema_two = Schema::array(Schema::Boolean);
483
484 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
485 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
486 assert!(
487 specification_eq_res,
488 "SpecificationEq: Equality of two Schema::Array failed!"
489 );
490 assert!(
491 struct_field_eq_res,
492 "StructFieldEq: Equality of two Schema::Array failed!"
493 );
494 assert_eq!(specification_eq_res, struct_field_eq_res);
495 }
496
497 #[test]
498 fn test_avro_3939_compare_decimal_schemata() {
499 let schema_one = Schema::Decimal(DecimalSchema {
500 precision: 10,
501 scale: 2,
502 inner: InnerDecimalSchema::Bytes,
503 });
504 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
505 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
506
507 let schema_two = Schema::Decimal(DecimalSchema {
508 precision: 10,
509 scale: 2,
510 inner: InnerDecimalSchema::Bytes,
511 });
512
513 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
514 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
515 assert!(
516 specification_eq_res,
517 "SpecificationEq: Equality of two Schema::Decimal failed!"
518 );
519 assert!(
520 struct_field_eq_res,
521 "StructFieldEq: Equality of two Schema::Decimal failed!"
522 );
523 assert_eq!(specification_eq_res, struct_field_eq_res);
524 }
525
526 #[test]
527 fn test_avro_3939_compare_fixed_schemata() {
528 let schema_one = Schema::Fixed(FixedSchema {
529 name: Name::try_from("fixed").expect("Name is valid"),
530 doc: None,
531 size: 10,
532 aliases: None,
533 attributes: BTreeMap::new(),
534 });
535 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
536 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
537
538 let schema_two = Schema::Fixed(FixedSchema {
539 name: Name::try_from("fixed").expect("Name is valid"),
540 doc: None,
541 size: 10,
542 aliases: None,
543 attributes: BTreeMap::new(),
544 });
545
546 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
547 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
548 assert!(
549 specification_eq_res,
550 "SpecificationEq: Equality of two Schema::Fixed failed!"
551 );
552 assert!(
553 struct_field_eq_res,
554 "StructFieldEq: Equality of two Schema::Fixed failed!"
555 );
556 assert_eq!(specification_eq_res, struct_field_eq_res);
557 }
558
559 #[test]
560 fn test_avro_3939_compare_enum_schemata() {
561 let schema_one = Schema::Enum(EnumSchema {
562 name: Name::try_from("enum").expect("Name is valid"),
563 doc: None,
564 symbols: vec!["A".to_string(), "B".to_string()],
565 default: None,
566 aliases: None,
567 attributes: BTreeMap::new(),
568 });
569 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
570 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
571
572 let schema_two = Schema::Enum(EnumSchema {
573 name: Name::try_from("enum").expect("Name is valid"),
574 doc: None,
575 symbols: vec!["A".to_string(), "B".to_string()],
576 default: None,
577 aliases: None,
578 attributes: BTreeMap::new(),
579 });
580
581 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
582 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
583 assert!(
584 specification_eq_res,
585 "SpecificationEq: Equality of two Schema::Enum failed!"
586 );
587 assert!(
588 struct_field_eq_res,
589 "StructFieldEq: Equality of two Schema::Enum failed!"
590 );
591 assert_eq!(specification_eq_res, struct_field_eq_res);
592 }
593
594 #[test]
595 fn test_avro_3939_compare_ref_schemata() {
596 let schema_one = Schema::Ref {
597 name: Name::try_from("ref").expect("Name is valid"),
598 };
599 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
600 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
601
602 let schema_two = Schema::Ref {
603 name: Name::try_from("ref").expect("Name is valid"),
604 };
605
606 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
607 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
608 assert!(
609 specification_eq_res,
610 "SpecificationEq: Equality of two Schema::Ref failed!"
611 );
612 assert!(
613 struct_field_eq_res,
614 "StructFieldEq: Equality of two Schema::Ref failed!"
615 );
616 assert_eq!(specification_eq_res, struct_field_eq_res);
617 }
618
619 #[test]
620 fn test_avro_3939_compare_record_schemata() {
621 let schema_one = Schema::Record(RecordSchema {
622 name: Name::try_from("record").expect("Name is valid"),
623 doc: None,
624 fields: vec![RecordField {
625 name: "field".to_string(),
626 doc: None,
627 default: None,
628 schema: Schema::Boolean,
629 order: RecordFieldOrder::Ignore,
630 aliases: None,
631 custom_attributes: BTreeMap::new(),
632 position: 0,
633 }],
634 aliases: None,
635 attributes: BTreeMap::new(),
636 lookup: Default::default(),
637 });
638 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
639 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
640
641 let schema_two = Schema::Record(RecordSchema {
642 name: Name::try_from("record").expect("Name is valid"),
643 doc: None,
644 fields: vec![RecordField {
645 name: "field".to_string(),
646 doc: None,
647 default: None,
648 schema: Schema::Boolean,
649 order: RecordFieldOrder::Ignore,
650 aliases: None,
651 custom_attributes: BTreeMap::new(),
652 position: 0,
653 }],
654 aliases: None,
655 attributes: BTreeMap::new(),
656 lookup: Default::default(),
657 });
658
659 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
660 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
661 assert!(
662 specification_eq_res,
663 "SpecificationEq: Equality of two Schema::Record failed!"
664 );
665 assert!(
666 struct_field_eq_res,
667 "StructFieldEq: Equality of two Schema::Record failed!"
668 );
669 assert_eq!(specification_eq_res, struct_field_eq_res);
670 }
671
672 #[test]
673 fn test_avro_3939_compare_union_schemata() -> TestResult {
674 let schema_one = Schema::Union(UnionSchema::new(vec![Schema::Boolean, Schema::Int])?);
675 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
676 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
677
678 let schema_two = Schema::Union(UnionSchema::new(vec![Schema::Boolean, Schema::Int])?);
679
680 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
681 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
682 assert!(
683 specification_eq_res,
684 "SpecificationEq: Equality of two Schema::Union failed!"
685 );
686 assert!(
687 struct_field_eq_res,
688 "StructFieldEq: Equality of two Schema::Union failed!"
689 );
690 assert_eq!(specification_eq_res, struct_field_eq_res);
691 Ok(())
692 }
693
694 #[test]
695 fn test_uuid_compare_uuid() -> TestResult {
696 let string = Schema::Uuid(UuidSchema::String);
697 let bytes = Schema::Uuid(UuidSchema::Bytes);
698 let mut fixed_schema = FixedSchema {
699 name: Name {
700 name: "some_name".to_string(),
701 namespace: None,
702 },
703 aliases: None,
704 doc: None,
705 size: 16,
706 attributes: Default::default(),
707 };
708 let fixed = Schema::Uuid(UuidSchema::Fixed(fixed_schema.clone()));
709 fixed_schema
710 .attributes
711 .insert("Something".to_string(), Value::Null);
712 let fixed_different = Schema::Uuid(UuidSchema::Fixed(fixed_schema));
713
714 assert!(SPECIFICATION_EQ.compare(&string, &string));
715 assert!(STRUCT_FIELD_EQ.compare(&string, &string));
716 assert!(SPECIFICATION_EQ.compare(&bytes, &bytes));
717 assert!(STRUCT_FIELD_EQ.compare(&bytes, &bytes));
718 assert!(SPECIFICATION_EQ.compare(&fixed, &fixed));
719 assert!(STRUCT_FIELD_EQ.compare(&fixed, &fixed));
720
721 assert!(!SPECIFICATION_EQ.compare(&string, &bytes));
722 assert!(!STRUCT_FIELD_EQ.compare(&string, &bytes));
723 assert!(!SPECIFICATION_EQ.compare(&bytes, &string));
724 assert!(!STRUCT_FIELD_EQ.compare(&bytes, &string));
725 assert!(!SPECIFICATION_EQ.compare(&string, &fixed));
726 assert!(!STRUCT_FIELD_EQ.compare(&string, &fixed));
727 assert!(!SPECIFICATION_EQ.compare(&fixed, &string));
728 assert!(!STRUCT_FIELD_EQ.compare(&fixed, &string));
729 assert!(!SPECIFICATION_EQ.compare(&bytes, &fixed));
730 assert!(!STRUCT_FIELD_EQ.compare(&bytes, &fixed));
731 assert!(!SPECIFICATION_EQ.compare(&fixed, &bytes));
732 assert!(!STRUCT_FIELD_EQ.compare(&fixed, &bytes));
733
734 assert!(SPECIFICATION_EQ.compare(&fixed, &fixed_different));
735 assert!(STRUCT_FIELD_EQ.compare(&fixed, &fixed_different));
736 assert!(SPECIFICATION_EQ.compare(&fixed_different, &fixed));
737 assert!(STRUCT_FIELD_EQ.compare(&fixed_different, &fixed));
738
739 let strict = StructFieldEq {
740 include_attributes: true,
741 };
742
743 assert!(!strict.compare(&fixed, &fixed_different));
744 assert!(!strict.compare(&fixed_different, &fixed));
745
746 Ok(())
747 }
748}