hybrid_array/
serde.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Support for serializing and deserializing `Array` using `serde`.

use crate::{Array, ArraySize};
use core::{fmt, marker::PhantomData};
use serde::{
    de::{self, Deserialize, Deserializer, SeqAccess, Visitor},
    ser::{Serialize, SerializeTuple, Serializer},
};

impl<'de, T, U> Deserialize<'de> for Array<T, U>
where
    T: Deserialize<'de>,
    U: ArraySize,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
        T: Deserialize<'de>,
    {
        struct ArrayVisitor<T> {
            element: PhantomData<T>,
        }

        impl<'de, T, U> Visitor<'de> for ArrayVisitor<Array<T, U>>
        where
            T: Deserialize<'de>,
            U: ArraySize,
        {
            type Value = Array<T, U>;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(formatter, "an array of length {}", U::USIZE)
            }

            fn visit_seq<A>(self, mut seq: A) -> Result<Array<T, U>, A::Error>
            where
                A: SeqAccess<'de>,
            {
                Array::<T, U>::try_from_fn(|i| {
                    seq.next_element()?
                        .ok_or_else(|| de::Error::invalid_length(i, &self))
                })
            }
        }

        let visitor = ArrayVisitor {
            element: PhantomData,
        };

        deserializer.deserialize_tuple(U::USIZE, visitor)
    }
}

impl<T, U> Serialize for Array<T, U>
where
    T: Serialize,
    U: ArraySize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut seq = serializer.serialize_tuple(U::USIZE)?;

        for elem in self {
            seq.serialize_element(elem)?;
        }

        seq.end()
    }
}

#[cfg(test)]
mod tests {
    const INTEGER_ARRAY_EXAMPLE: [u64; 4] = [1, 2, 3, 4];
    use crate::{
        sizes::{U4, U5},
        Array,
    };

    #[test]
    fn deserialize_integer_array() {
        let serialized = bincode::serialize(&INTEGER_ARRAY_EXAMPLE).unwrap();
        let deserialized: Array<u64, U4> = bincode::deserialize(&serialized).unwrap();
        assert_eq!(deserialized, INTEGER_ARRAY_EXAMPLE);
    }

    #[test]
    fn deserialize_too_short() {
        let serialized = bincode::serialize(&INTEGER_ARRAY_EXAMPLE).unwrap();
        let deserialized: Result<Array<u64, U5>, bincode::Error> =
            bincode::deserialize(&serialized);

        // TODO(tarcieri): check for more specific error type
        assert!(deserialized.is_err())
    }

    #[test]
    fn serialize_integer_array() {
        let example: Array<u64, U4> = Array(INTEGER_ARRAY_EXAMPLE);
        let serialized = bincode::serialize(&example).unwrap();
        let deserialized: Array<u64, U4> = bincode::deserialize(&serialized).unwrap();
        assert_eq!(example, deserialized);
    }
}