1use crate::{
19 AvroResult, Error,
20 bigdecimal::deserialize_big_decimal,
21 decimal::Decimal,
22 duration::Duration,
23 error::Details,
24 schema::{
25 DecimalSchema, EnumSchema, FixedSchema, Name, Namespace, RecordSchema, ResolvedSchema,
26 Schema,
27 },
28 types::Value,
29 util::{safe_len, zag_i32, zag_i64},
30};
31use std::{
32 borrow::Borrow,
33 collections::HashMap,
34 io::{ErrorKind, Read},
35};
36use uuid::Uuid;
37
38#[inline]
39pub(crate) fn decode_long<R: Read>(reader: &mut R) -> AvroResult<Value> {
40 zag_i64(reader).map(Value::Long)
41}
42
43#[inline]
44fn decode_int<R: Read>(reader: &mut R) -> AvroResult<Value> {
45 zag_i32(reader).map(Value::Int)
46}
47
48#[inline]
49pub(crate) fn decode_len<R: Read>(reader: &mut R) -> AvroResult<usize> {
50 let len = zag_i64(reader)?;
51 safe_len(usize::try_from(len).map_err(|e| Details::ConvertI64ToUsize(e, len))?)
52}
53
54fn decode_seq_len<R: Read>(reader: &mut R) -> AvroResult<usize> {
59 let raw_len = zag_i64(reader)?;
60 safe_len(
61 usize::try_from(match raw_len.cmp(&0) {
62 std::cmp::Ordering::Equal => return Ok(0),
63 std::cmp::Ordering::Less => {
64 let _size = zag_i64(reader)?;
65 raw_len.checked_neg().ok_or(Details::IntegerOverflow)?
66 }
67 std::cmp::Ordering::Greater => raw_len,
68 })
69 .map_err(|e| Details::ConvertI64ToUsize(e, raw_len))?,
70 )
71}
72
73pub fn decode<R: Read>(schema: &Schema, reader: &mut R) -> AvroResult<Value> {
75 let rs = ResolvedSchema::try_from(schema)?;
76 decode_internal(schema, rs.get_names(), &None, reader)
77}
78
79pub(crate) fn decode_internal<R: Read, S: Borrow<Schema>>(
80 schema: &Schema,
81 names: &HashMap<Name, S>,
82 enclosing_namespace: &Namespace,
83 reader: &mut R,
84) -> AvroResult<Value> {
85 match *schema {
86 Schema::Null => Ok(Value::Null),
87 Schema::Boolean => {
88 let mut buf = [0u8; 1];
89 match reader.read_exact(&mut buf[..]) {
90 Ok(_) => match buf[0] {
91 0u8 => Ok(Value::Boolean(false)),
92 1u8 => Ok(Value::Boolean(true)),
93 _ => Err(Details::BoolValue(buf[0]).into()),
94 },
95 Err(io_err) => {
96 if let ErrorKind::UnexpectedEof = io_err.kind() {
97 Ok(Value::Null)
98 } else {
99 Err(Details::ReadBoolean(io_err).into())
100 }
101 }
102 }
103 }
104 Schema::Decimal(DecimalSchema { ref inner, .. }) => match &**inner {
105 Schema::Fixed { .. } => {
106 match decode_internal(inner, names, enclosing_namespace, reader)? {
107 Value::Fixed(_, bytes) => Ok(Value::Decimal(Decimal::from(bytes))),
108 value => Err(Details::FixedValue(value).into()),
109 }
110 }
111 Schema::Bytes => match decode_internal(inner, names, enclosing_namespace, reader)? {
112 Value::Bytes(bytes) => Ok(Value::Decimal(Decimal::from(bytes))),
113 value => Err(Details::BytesValue(value).into()),
114 },
115 schema => Err(Details::ResolveDecimalSchema(schema.into()).into()),
116 },
117 Schema::BigDecimal => {
118 match decode_internal(&Schema::Bytes, names, enclosing_namespace, reader)? {
119 Value::Bytes(bytes) => deserialize_big_decimal(&bytes).map(Value::BigDecimal),
120 value => Err(Details::BytesValue(value).into()),
121 }
122 }
123 Schema::Uuid => {
124 let Value::Bytes(bytes) =
125 decode_internal(&Schema::Bytes, names, enclosing_namespace, reader)?
126 else {
127 unreachable!();
129 };
130
131 let uuid = if bytes.len() == 16 {
132 Uuid::from_slice(&bytes).map_err(Details::ConvertSliceToUuid)?
133 } else {
134 let string = std::str::from_utf8(&bytes).map_err(Details::ConvertToUtf8Error)?;
135 Uuid::parse_str(string).map_err(Details::ConvertStrToUuid)?
136 };
137 Ok(Value::Uuid(uuid))
138 }
139 Schema::Int => decode_int(reader),
140 Schema::Date => zag_i32(reader).map(Value::Date),
141 Schema::TimeMillis => zag_i32(reader).map(Value::TimeMillis),
142 Schema::Long => decode_long(reader),
143 Schema::TimeMicros => zag_i64(reader).map(Value::TimeMicros),
144 Schema::TimestampMillis => zag_i64(reader).map(Value::TimestampMillis),
145 Schema::TimestampMicros => zag_i64(reader).map(Value::TimestampMicros),
146 Schema::TimestampNanos => zag_i64(reader).map(Value::TimestampNanos),
147 Schema::LocalTimestampMillis => zag_i64(reader).map(Value::LocalTimestampMillis),
148 Schema::LocalTimestampMicros => zag_i64(reader).map(Value::LocalTimestampMicros),
149 Schema::LocalTimestampNanos => zag_i64(reader).map(Value::LocalTimestampNanos),
150 Schema::Duration => {
151 let mut buf = [0u8; 12];
152 reader.read_exact(&mut buf).map_err(Details::ReadDuration)?;
153 Ok(Value::Duration(Duration::from(buf)))
154 }
155 Schema::Float => {
156 let mut buf = [0u8; std::mem::size_of::<f32>()];
157 reader
158 .read_exact(&mut buf[..])
159 .map_err(Details::ReadFloat)?;
160 Ok(Value::Float(f32::from_le_bytes(buf)))
161 }
162 Schema::Double => {
163 let mut buf = [0u8; std::mem::size_of::<f64>()];
164 reader
165 .read_exact(&mut buf[..])
166 .map_err(Details::ReadDouble)?;
167 Ok(Value::Double(f64::from_le_bytes(buf)))
168 }
169 Schema::Bytes => {
170 let len = decode_len(reader)?;
171 let mut buf = vec![0u8; len];
172 reader.read_exact(&mut buf).map_err(Details::ReadBytes)?;
173 Ok(Value::Bytes(buf))
174 }
175 Schema::String => {
176 let len = decode_len(reader)?;
177 let mut buf = vec![0u8; len];
178 match reader.read_exact(&mut buf) {
179 Ok(_) => Ok(Value::String(
180 String::from_utf8(buf).map_err(Details::ConvertToUtf8)?,
181 )),
182 Err(io_err) => {
183 if let ErrorKind::UnexpectedEof = io_err.kind() {
184 Ok(Value::Null)
185 } else {
186 Err(Details::ReadString(io_err).into())
187 }
188 }
189 }
190 }
191 Schema::Fixed(FixedSchema { size, .. }) => {
192 let mut buf = vec![0u8; size];
193 reader
194 .read_exact(&mut buf)
195 .map_err(|e| Details::ReadFixed(e, size))?;
196 Ok(Value::Fixed(size, buf))
197 }
198 Schema::Array(ref inner) => {
199 let mut items = Vec::new();
200
201 loop {
202 let len = decode_seq_len(reader)?;
203 if len == 0 {
204 break;
205 }
206
207 items.reserve(len);
208 for _ in 0..len {
209 items.push(decode_internal(
210 &inner.items,
211 names,
212 enclosing_namespace,
213 reader,
214 )?);
215 }
216 }
217
218 Ok(Value::Array(items))
219 }
220 Schema::Map(ref inner) => {
221 let mut items = HashMap::new();
222
223 loop {
224 let len = decode_seq_len(reader)?;
225 if len == 0 {
226 break;
227 }
228
229 items.reserve(len);
230 for _ in 0..len {
231 match decode_internal(&Schema::String, names, enclosing_namespace, reader)? {
232 Value::String(key) => {
233 let value =
234 decode_internal(&inner.types, names, enclosing_namespace, reader)?;
235 items.insert(key, value);
236 }
237 value => return Err(Details::MapKeyType(value.into()).into()),
238 }
239 }
240 }
241
242 Ok(Value::Map(items))
243 }
244 Schema::Union(ref inner) => match zag_i64(reader).map_err(Error::into_details) {
245 Ok(index) => {
246 let variants = inner.variants();
247 let variant = variants
248 .get(usize::try_from(index).map_err(|e| Details::ConvertI64ToUsize(e, index))?)
249 .ok_or(Details::GetUnionVariant {
250 index,
251 num_variants: variants.len(),
252 })?;
253 let value = decode_internal(variant, names, enclosing_namespace, reader)?;
254 Ok(Value::Union(index as u32, Box::new(value)))
255 }
256 Err(Details::ReadVariableIntegerBytes(io_err)) => {
257 if let ErrorKind::UnexpectedEof = io_err.kind() {
258 Ok(Value::Union(0, Box::new(Value::Null)))
259 } else {
260 Err(Details::ReadVariableIntegerBytes(io_err).into())
261 }
262 }
263 Err(io_err) => Err(Error::new(io_err)),
264 },
265 Schema::Record(RecordSchema {
266 ref name,
267 ref fields,
268 ..
269 }) => {
270 let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
271 let mut items = Vec::with_capacity(fields.len());
273 for field in fields {
274 items.push((
276 field.name.clone(),
277 decode_internal(
278 &field.schema,
279 names,
280 &fully_qualified_name.namespace,
281 reader,
282 )?,
283 ));
284 }
285 Ok(Value::Record(items))
286 }
287 Schema::Enum(EnumSchema { ref symbols, .. }) => {
288 Ok(if let Value::Int(raw_index) = decode_int(reader)? {
289 let index = usize::try_from(raw_index)
290 .map_err(|e| Details::ConvertI32ToUsize(e, raw_index))?;
291 if (0..symbols.len()).contains(&index) {
292 let symbol = symbols[index].clone();
293 Value::Enum(raw_index as u32, symbol)
294 } else {
295 return Err(Details::GetEnumValue {
296 index,
297 nsymbols: symbols.len(),
298 }
299 .into());
300 }
301 } else {
302 return Err(Details::GetEnumUnknownIndexValue.into());
303 })
304 }
305 Schema::Ref { ref name } => {
306 let fully_qualified_name = name.fully_qualified_name(enclosing_namespace);
307 if let Some(resolved) = names.get(&fully_qualified_name) {
308 decode_internal(
309 resolved.borrow(),
310 names,
311 &fully_qualified_name.namespace,
312 reader,
313 )
314 } else {
315 Err(Details::SchemaResolutionError(fully_qualified_name).into())
316 }
317 }
318 }
319}
320
321#[cfg(test)]
322#[allow(clippy::expect_fun_call)]
323mod tests {
324 use crate::{
325 Decimal,
326 decode::decode,
327 encode::{encode, tests::success},
328 schema::{DecimalSchema, FixedSchema, Schema},
329 types::{
330 Value,
331 Value::{Array, Int, Map},
332 },
333 };
334 use apache_avro_test_helper::TestResult;
335 use pretty_assertions::assert_eq;
336 use std::collections::HashMap;
337 use uuid::Uuid;
338
339 #[test]
340 fn test_decode_array_without_size() -> TestResult {
341 let mut input: &[u8] = &[6, 2, 4, 6, 0];
342 let result = decode(&Schema::array(Schema::Int), &mut input);
343 assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?);
344
345 Ok(())
346 }
347
348 #[test]
349 fn test_decode_array_with_size() -> TestResult {
350 let mut input: &[u8] = &[5, 6, 2, 4, 6, 0];
351 let result = decode(&Schema::array(Schema::Int), &mut input);
352 assert_eq!(Array(vec!(Int(1), Int(2), Int(3))), result?);
353
354 Ok(())
355 }
356
357 #[test]
358 fn test_decode_map_without_size() -> TestResult {
359 let mut input: &[u8] = &[0x02, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00];
360 let result = decode(&Schema::map(Schema::Int), &mut input);
361 let mut expected = HashMap::new();
362 expected.insert(String::from("test"), Int(1));
363 assert_eq!(Map(expected), result?);
364
365 Ok(())
366 }
367
368 #[test]
369 fn test_decode_map_with_size() -> TestResult {
370 let mut input: &[u8] = &[0x01, 0x0C, 0x08, 0x74, 0x65, 0x73, 0x74, 0x02, 0x00];
371 let result = decode(&Schema::map(Schema::Int), &mut input);
372 let mut expected = HashMap::new();
373 expected.insert(String::from("test"), Int(1));
374 assert_eq!(Map(expected), result?);
375
376 Ok(())
377 }
378
379 #[test]
380 fn test_negative_decimal_value() -> TestResult {
381 use crate::{encode::encode, schema::Name};
382 use num_bigint::ToBigInt;
383 let inner = Box::new(Schema::Fixed(
384 FixedSchema::builder()
385 .name(Name::new("decimal")?)
386 .size(2)
387 .build(),
388 ));
389 let schema = Schema::Decimal(DecimalSchema {
390 inner,
391 precision: 4,
392 scale: 2,
393 });
394 let bigint = (-423).to_bigint().unwrap();
395 let value = Value::Decimal(Decimal::from(bigint.to_signed_bytes_be()));
396
397 let mut buffer = Vec::new();
398 encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
399
400 let mut bytes = &buffer[..];
401 let result = decode(&schema, &mut bytes)?;
402 assert_eq!(result, value);
403
404 Ok(())
405 }
406
407 #[test]
408 fn test_decode_decimal_with_bigger_than_necessary_size() -> TestResult {
409 use crate::{encode::encode, schema::Name};
410 use num_bigint::ToBigInt;
411 let inner = Box::new(Schema::Fixed(FixedSchema {
412 size: 13,
413 name: Name::new("decimal")?,
414 aliases: None,
415 doc: None,
416 default: None,
417 attributes: Default::default(),
418 }));
419 let schema = Schema::Decimal(DecimalSchema {
420 inner,
421 precision: 4,
422 scale: 2,
423 });
424 let value = Value::Decimal(Decimal::from(
425 ((-423).to_bigint().unwrap()).to_signed_bytes_be(),
426 ));
427 let mut buffer = Vec::<u8>::new();
428
429 encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
430 let mut bytes: &[u8] = &buffer[..];
431 let result = decode(&schema, &mut bytes)?;
432 assert_eq!(result, value);
433
434 Ok(())
435 }
436
437 #[test]
438 fn test_avro_3448_recursive_definition_decode_union() -> TestResult {
439 let schema = Schema::parse_str(
441 r#"
442 {
443 "type":"record",
444 "name":"TestStruct",
445 "fields": [
446 {
447 "name":"a",
448 "type":[ "null", {
449 "type":"record",
450 "name": "Inner",
451 "fields": [ {
452 "name":"z",
453 "type":"int"
454 }]
455 }]
456 },
457 {
458 "name":"b",
459 "type":"Inner"
460 }
461 ]
462 }"#,
463 )?;
464
465 let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
466 let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
467 let outer_value1 = Value::Record(vec![
468 ("a".into(), Value::Union(1, Box::new(inner_value1))),
469 ("b".into(), inner_value2.clone()),
470 ]);
471 let mut buf = Vec::new();
472 encode(&outer_value1, &schema, &mut buf).expect(&success(&outer_value1, &schema));
473 assert!(!buf.is_empty());
474 let mut bytes = &buf[..];
475 assert_eq!(
476 outer_value1,
477 decode(&schema, &mut bytes).expect(&format!(
478 "Failed to decode using recursive definitions with schema:\n {:?}\n",
479 &schema
480 ))
481 );
482
483 let mut buf = Vec::new();
484 let outer_value2 = Value::Record(vec![
485 ("a".into(), Value::Union(0, Box::new(Value::Null))),
486 ("b".into(), inner_value2),
487 ]);
488 encode(&outer_value2, &schema, &mut buf).expect(&success(&outer_value2, &schema));
489 let mut bytes = &buf[..];
490 assert_eq!(
491 outer_value2,
492 decode(&schema, &mut bytes).expect(&format!(
493 "Failed to decode using recursive definitions with schema:\n {:?}\n",
494 &schema
495 ))
496 );
497
498 Ok(())
499 }
500
501 #[test]
502 fn test_avro_3448_recursive_definition_decode_array() -> TestResult {
503 let schema = Schema::parse_str(
504 r#"
505 {
506 "type":"record",
507 "name":"TestStruct",
508 "fields": [
509 {
510 "name":"a",
511 "type":{
512 "type":"array",
513 "items": {
514 "type":"record",
515 "name": "Inner",
516 "fields": [ {
517 "name":"z",
518 "type":"int"
519 }]
520 }
521 }
522 },
523 {
524 "name":"b",
525 "type": "Inner"
526 }
527 ]
528 }"#,
529 )?;
530
531 let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
532 let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
533 let outer_value = Value::Record(vec![
534 ("a".into(), Value::Array(vec![inner_value1])),
535 ("b".into(), inner_value2),
536 ]);
537 let mut buf = Vec::new();
538 encode(&outer_value, &schema, &mut buf).expect(&success(&outer_value, &schema));
539 let mut bytes = &buf[..];
540 assert_eq!(
541 outer_value,
542 decode(&schema, &mut bytes).expect(&format!(
543 "Failed to decode using recursive definitions with schema:\n {:?}\n",
544 &schema
545 ))
546 );
547
548 Ok(())
549 }
550
551 #[test]
552 fn test_avro_3448_recursive_definition_decode_map() -> TestResult {
553 let schema = Schema::parse_str(
554 r#"
555 {
556 "type":"record",
557 "name":"TestStruct",
558 "fields": [
559 {
560 "name":"a",
561 "type":{
562 "type":"map",
563 "values": {
564 "type":"record",
565 "name": "Inner",
566 "fields": [ {
567 "name":"z",
568 "type":"int"
569 }]
570 }
571 }
572 },
573 {
574 "name":"b",
575 "type": "Inner"
576 }
577 ]
578 }"#,
579 )?;
580
581 let inner_value1 = Value::Record(vec![("z".into(), Value::Int(3))]);
582 let inner_value2 = Value::Record(vec![("z".into(), Value::Int(6))]);
583 let outer_value = Value::Record(vec![
584 (
585 "a".into(),
586 Value::Map(vec![("akey".into(), inner_value1)].into_iter().collect()),
587 ),
588 ("b".into(), inner_value2),
589 ]);
590 let mut buf = Vec::new();
591 encode(&outer_value, &schema, &mut buf).expect(&success(&outer_value, &schema));
592 let mut bytes = &buf[..];
593 assert_eq!(
594 outer_value,
595 decode(&schema, &mut bytes).expect(&format!(
596 "Failed to decode using recursive definitions with schema:\n {:?}\n",
597 &schema
598 ))
599 );
600
601 Ok(())
602 }
603
604 #[test]
605 fn test_avro_3448_proper_multi_level_decoding_middle_namespace() -> TestResult {
606 let schema = r#"
608 {
609 "name": "record_name",
610 "namespace": "space",
611 "type": "record",
612 "fields": [
613 {
614 "name": "outer_field_1",
615 "type": [
616 "null",
617 {
618 "type": "record",
619 "name": "middle_record_name",
620 "namespace":"middle_namespace",
621 "fields":[
622 {
623 "name":"middle_field_1",
624 "type":[
625 "null",
626 {
627 "type":"record",
628 "name":"inner_record_name",
629 "fields":[
630 {
631 "name":"inner_field_1",
632 "type":"double"
633 }
634 ]
635 }
636 ]
637 }
638 ]
639 }
640 ]
641 },
642 {
643 "name": "outer_field_2",
644 "type" : "middle_namespace.inner_record_name"
645 }
646 ]
647 }
648 "#;
649 let schema = Schema::parse_str(schema)?;
650 let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
651 let middle_record_variation_1 = Value::Record(vec![(
652 "middle_field_1".into(),
653 Value::Union(0, Box::new(Value::Null)),
654 )]);
655 let middle_record_variation_2 = Value::Record(vec![(
656 "middle_field_1".into(),
657 Value::Union(1, Box::new(inner_record.clone())),
658 )]);
659 let outer_record_variation_1 = Value::Record(vec![
660 (
661 "outer_field_1".into(),
662 Value::Union(0, Box::new(Value::Null)),
663 ),
664 ("outer_field_2".into(), inner_record.clone()),
665 ]);
666 let outer_record_variation_2 = Value::Record(vec![
667 (
668 "outer_field_1".into(),
669 Value::Union(1, Box::new(middle_record_variation_1)),
670 ),
671 ("outer_field_2".into(), inner_record.clone()),
672 ]);
673 let outer_record_variation_3 = Value::Record(vec![
674 (
675 "outer_field_1".into(),
676 Value::Union(1, Box::new(middle_record_variation_2)),
677 ),
678 ("outer_field_2".into(), inner_record),
679 ]);
680
681 let mut buf = Vec::new();
682 encode(&outer_record_variation_1, &schema, &mut buf)
683 .expect(&success(&outer_record_variation_1, &schema));
684 let mut bytes = &buf[..];
685 assert_eq!(
686 outer_record_variation_1,
687 decode(&schema, &mut bytes).expect(&format!(
688 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
689 &schema
690 ))
691 );
692
693 let mut buf = Vec::new();
694 encode(&outer_record_variation_2, &schema, &mut buf)
695 .expect(&success(&outer_record_variation_2, &schema));
696 let mut bytes = &buf[..];
697 assert_eq!(
698 outer_record_variation_2,
699 decode(&schema, &mut bytes).expect(&format!(
700 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
701 &schema
702 ))
703 );
704
705 let mut buf = Vec::new();
706 encode(&outer_record_variation_3, &schema, &mut buf)
707 .expect(&success(&outer_record_variation_3, &schema));
708 let mut bytes = &buf[..];
709 assert_eq!(
710 outer_record_variation_3,
711 decode(&schema, &mut bytes).expect(&format!(
712 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
713 &schema
714 ))
715 );
716
717 Ok(())
718 }
719
720 #[test]
721 fn test_avro_3448_proper_multi_level_decoding_inner_namespace() -> TestResult {
722 let schema = r#"
724 {
725 "name": "record_name",
726 "namespace": "space",
727 "type": "record",
728 "fields": [
729 {
730 "name": "outer_field_1",
731 "type": [
732 "null",
733 {
734 "type": "record",
735 "name": "middle_record_name",
736 "namespace":"middle_namespace",
737 "fields":[
738 {
739 "name":"middle_field_1",
740 "type":[
741 "null",
742 {
743 "type":"record",
744 "name":"inner_record_name",
745 "namespace":"inner_namespace",
746 "fields":[
747 {
748 "name":"inner_field_1",
749 "type":"double"
750 }
751 ]
752 }
753 ]
754 }
755 ]
756 }
757 ]
758 },
759 {
760 "name": "outer_field_2",
761 "type" : "inner_namespace.inner_record_name"
762 }
763 ]
764 }
765 "#;
766 let schema = Schema::parse_str(schema)?;
767 let inner_record = Value::Record(vec![("inner_field_1".into(), Value::Double(5.4))]);
768 let middle_record_variation_1 = Value::Record(vec![(
769 "middle_field_1".into(),
770 Value::Union(0, Box::new(Value::Null)),
771 )]);
772 let middle_record_variation_2 = Value::Record(vec![(
773 "middle_field_1".into(),
774 Value::Union(1, Box::new(inner_record.clone())),
775 )]);
776 let outer_record_variation_1 = Value::Record(vec![
777 (
778 "outer_field_1".into(),
779 Value::Union(0, Box::new(Value::Null)),
780 ),
781 ("outer_field_2".into(), inner_record.clone()),
782 ]);
783 let outer_record_variation_2 = Value::Record(vec![
784 (
785 "outer_field_1".into(),
786 Value::Union(1, Box::new(middle_record_variation_1)),
787 ),
788 ("outer_field_2".into(), inner_record.clone()),
789 ]);
790 let outer_record_variation_3 = Value::Record(vec![
791 (
792 "outer_field_1".into(),
793 Value::Union(1, Box::new(middle_record_variation_2)),
794 ),
795 ("outer_field_2".into(), inner_record),
796 ]);
797
798 let mut buf = Vec::new();
799 encode(&outer_record_variation_1, &schema, &mut buf)
800 .expect(&success(&outer_record_variation_1, &schema));
801 let mut bytes = &buf[..];
802 assert_eq!(
803 outer_record_variation_1,
804 decode(&schema, &mut bytes).expect(&format!(
805 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
806 &schema
807 ))
808 );
809
810 let mut buf = Vec::new();
811 encode(&outer_record_variation_2, &schema, &mut buf)
812 .expect(&success(&outer_record_variation_2, &schema));
813 let mut bytes = &buf[..];
814 assert_eq!(
815 outer_record_variation_2,
816 decode(&schema, &mut bytes).expect(&format!(
817 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
818 &schema
819 ))
820 );
821
822 let mut buf = Vec::new();
823 encode(&outer_record_variation_3, &schema, &mut buf)
824 .expect(&success(&outer_record_variation_3, &schema));
825 let mut bytes = &buf[..];
826 assert_eq!(
827 outer_record_variation_3,
828 decode(&schema, &mut bytes).expect(&format!(
829 "Failed to Decode with recursively defined namespace with schema:\n {:?}\n",
830 &schema
831 ))
832 );
833
834 Ok(())
835 }
836
837 #[test]
838 fn avro_3926_encode_decode_uuid_to_string() -> TestResult {
839 use crate::encode::encode;
840
841 let schema = Schema::String;
842 let value = Value::Uuid(Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?);
843
844 let mut buffer = Vec::new();
845 encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
846
847 let result = decode(&Schema::Uuid, &mut &buffer[..])?;
848 assert_eq!(result, value);
849
850 Ok(())
851 }
852
853 #[test]
854 fn avro_3926_encode_decode_uuid_to_fixed() -> TestResult {
855 use crate::encode::encode;
856
857 let schema = Schema::Fixed(FixedSchema {
858 size: 16,
859 name: "uuid".into(),
860 aliases: None,
861 doc: None,
862 default: None,
863 attributes: Default::default(),
864 });
865 let value = Value::Uuid(Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?);
866
867 let mut buffer = Vec::new();
868 encode(&value, &schema, &mut buffer).expect(&success(&value, &schema));
869
870 let result = decode(&Schema::Uuid, &mut &buffer[..])?;
871 assert_eq!(result, value);
872
873 Ok(())
874 }
875}