apache_avro/
decode.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use 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
54/// Decode the length of a sequence.
55///
56/// Maps and arrays are 0-terminated, 0i64 is also encoded as 0 in Avro reading a length of 0 means
57/// the end of the map or array.
58fn 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
73/// Decode a `Value` from avro format given its `Schema`.
74pub 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                // Calling decode_internal with Schema::Bytes can only return a Value::Bytes or an error
128                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            // Benchmarks indicate ~10% improvement using this method.
272            let mut items = Vec::with_capacity(fields.len());
273            for field in fields {
274                // TODO: This clone is also expensive. See if we can do away with it...
275                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        // if encoding fails in this test check the corresponding test in encode
440        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        // if encoding fails in this test check the corresponding test in encode
607        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        // if encoding fails in this test check the corresponding test in encode
723        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}