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
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(Schema::Boolean)
428 .attributes(BTreeMap::from_iter([(
429 "key1".to_string(),
430 Value::Bool(true),
431 )]))
432 .build();
433 let schema_two = Schema::map(Schema::Boolean)
434 .attributes(BTreeMap::from_iter([(
435 "key2".to_string(),
436 Value::Bool(true),
437 )]))
438 .build();
439 assert!(STRUCT_FIELD_EQ.compare(&schema_one, &schema_two));
441 }
442
443 #[test]
444 fn test_avro_3939_compare_schemata_including_attributes() {
445 let struct_field_eq = StructFieldEq {
446 include_attributes: true,
447 };
448 let schema_one = Schema::map(Schema::Boolean)
449 .attributes(BTreeMap::from_iter([(
450 "key1".to_string(),
451 Value::Bool(true),
452 )]))
453 .build();
454 let schema_two = Schema::map(Schema::Boolean)
455 .attributes(BTreeMap::from_iter([(
456 "key2".to_string(),
457 Value::Bool(true),
458 )]))
459 .build();
460 assert!(!struct_field_eq.compare(&schema_one, &schema_two));
461 }
462
463 #[test]
464 fn test_avro_3939_compare_map_schemata() {
465 let schema_one = Schema::map(Schema::Boolean).build();
466 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
467 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
468
469 let schema_two = Schema::map(Schema::Boolean).build();
470
471 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
472 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
473 assert!(
474 specification_eq_res,
475 "SpecificationEq: Equality of two Schema::Map failed!"
476 );
477 assert!(
478 struct_field_eq_res,
479 "StructFieldEq: Equality of two Schema::Map failed!"
480 );
481 assert_eq!(specification_eq_res, struct_field_eq_res);
482 }
483
484 #[test]
485 fn test_avro_3939_compare_array_schemata() {
486 let schema_one = Schema::array(Schema::Boolean).build();
487 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
488 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
489
490 let schema_two = Schema::array(Schema::Boolean).build();
491
492 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
493 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
494 assert!(
495 specification_eq_res,
496 "SpecificationEq: Equality of two Schema::Array failed!"
497 );
498 assert!(
499 struct_field_eq_res,
500 "StructFieldEq: Equality of two Schema::Array failed!"
501 );
502 assert_eq!(specification_eq_res, struct_field_eq_res);
503 }
504
505 #[test]
506 fn test_avro_3939_compare_decimal_schemata() {
507 let schema_one = Schema::Decimal(DecimalSchema {
508 precision: 10,
509 scale: 2,
510 inner: InnerDecimalSchema::Bytes,
511 });
512 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
513 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
514
515 let schema_two = Schema::Decimal(DecimalSchema {
516 precision: 10,
517 scale: 2,
518 inner: InnerDecimalSchema::Bytes,
519 });
520
521 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
522 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
523 assert!(
524 specification_eq_res,
525 "SpecificationEq: Equality of two Schema::Decimal failed!"
526 );
527 assert!(
528 struct_field_eq_res,
529 "StructFieldEq: Equality of two Schema::Decimal failed!"
530 );
531 assert_eq!(specification_eq_res, struct_field_eq_res);
532 }
533
534 #[test]
535 fn test_avro_3939_compare_fixed_schemata() {
536 let schema_one = Schema::Fixed(FixedSchema {
537 name: Name::try_from("fixed").expect("Name is valid"),
538 doc: None,
539 size: 10,
540 aliases: None,
541 attributes: BTreeMap::new(),
542 });
543 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
544 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
545
546 let schema_two = Schema::Fixed(FixedSchema {
547 name: Name::try_from("fixed").expect("Name is valid"),
548 doc: None,
549 size: 10,
550 aliases: None,
551 attributes: BTreeMap::new(),
552 });
553
554 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
555 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
556 assert!(
557 specification_eq_res,
558 "SpecificationEq: Equality of two Schema::Fixed failed!"
559 );
560 assert!(
561 struct_field_eq_res,
562 "StructFieldEq: Equality of two Schema::Fixed failed!"
563 );
564 assert_eq!(specification_eq_res, struct_field_eq_res);
565 }
566
567 #[test]
568 fn test_avro_3939_compare_enum_schemata() {
569 let schema_one = Schema::Enum(EnumSchema {
570 name: Name::try_from("enum").expect("Name is valid"),
571 doc: None,
572 symbols: vec!["A".to_string(), "B".to_string()],
573 default: None,
574 aliases: None,
575 attributes: BTreeMap::new(),
576 });
577 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
578 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
579
580 let schema_two = Schema::Enum(EnumSchema {
581 name: Name::try_from("enum").expect("Name is valid"),
582 doc: None,
583 symbols: vec!["A".to_string(), "B".to_string()],
584 default: None,
585 aliases: None,
586 attributes: BTreeMap::new(),
587 });
588
589 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
590 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
591 assert!(
592 specification_eq_res,
593 "SpecificationEq: Equality of two Schema::Enum failed!"
594 );
595 assert!(
596 struct_field_eq_res,
597 "StructFieldEq: Equality of two Schema::Enum failed!"
598 );
599 assert_eq!(specification_eq_res, struct_field_eq_res);
600 }
601
602 #[test]
603 fn test_avro_3939_compare_ref_schemata() {
604 let schema_one = Schema::Ref {
605 name: Name::try_from("ref").expect("Name is valid"),
606 };
607 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
608 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
609
610 let schema_two = Schema::Ref {
611 name: Name::try_from("ref").expect("Name is valid"),
612 };
613
614 let specification_eq_res = SPECIFICATION_EQ.compare(&schema_one, &schema_two);
615 let struct_field_eq_res = STRUCT_FIELD_EQ.compare(&schema_one, &schema_two);
616 assert!(
617 specification_eq_res,
618 "SpecificationEq: Equality of two Schema::Ref failed!"
619 );
620 assert!(
621 struct_field_eq_res,
622 "StructFieldEq: Equality of two Schema::Ref failed!"
623 );
624 assert_eq!(specification_eq_res, struct_field_eq_res);
625 }
626
627 #[test]
628 fn test_avro_3939_compare_record_schemata() {
629 let schema_one = Schema::Record(RecordSchema {
630 name: Name::try_from("record").expect("Name is valid"),
631 doc: None,
632 fields: vec![
633 RecordField::builder()
634 .name("field".to_string())
635 .schema(Schema::Boolean)
636 .build(),
637 ],
638 aliases: None,
639 attributes: BTreeMap::new(),
640 lookup: Default::default(),
641 });
642 assert!(!SPECIFICATION_EQ.compare(&schema_one, &Schema::Boolean));
643 assert!(!STRUCT_FIELD_EQ.compare(&schema_one, &Schema::Boolean));
644
645 let schema_two = Schema::Record(RecordSchema {
646 name: Name::try_from("record").expect("Name is valid"),
647 doc: None,
648 fields: vec![
649 RecordField::builder()
650 .name("field".to_string())
651 .schema(Schema::Boolean)
652 .build(),
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}