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