hybrid_array/
serde.rs

1//! Support for serializing and deserializing `Array` using `serde`.
2
3use crate::{Array, ArraySize};
4use core::{fmt, marker::PhantomData};
5use serde::{
6    de::{self, Deserialize, Deserializer, SeqAccess, Visitor},
7    ser::{Serialize, SerializeTuple, Serializer},
8};
9
10impl<'de, T, U> Deserialize<'de> for Array<T, U>
11where
12    T: Deserialize<'de>,
13    U: ArraySize,
14{
15    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
16    where
17        D: Deserializer<'de>,
18        T: Deserialize<'de>,
19    {
20        struct ArrayVisitor<T> {
21            element: PhantomData<T>,
22        }
23
24        impl<'de, T, U> Visitor<'de> for ArrayVisitor<Array<T, U>>
25        where
26            T: Deserialize<'de>,
27            U: ArraySize,
28        {
29            type Value = Array<T, U>;
30
31            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32                write!(formatter, "an array of length {}", U::USIZE)
33            }
34
35            fn visit_seq<A>(self, mut seq: A) -> Result<Array<T, U>, A::Error>
36            where
37                A: SeqAccess<'de>,
38            {
39                Array::<T, U>::try_from_fn(|i| {
40                    seq.next_element()?
41                        .ok_or_else(|| de::Error::invalid_length(i, &self))
42                })
43            }
44        }
45
46        let visitor = ArrayVisitor {
47            element: PhantomData,
48        };
49
50        deserializer.deserialize_tuple(U::USIZE, visitor)
51    }
52}
53
54impl<T, U> Serialize for Array<T, U>
55where
56    T: Serialize,
57    U: ArraySize,
58{
59    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60    where
61        S: Serializer,
62    {
63        let mut seq = serializer.serialize_tuple(U::USIZE)?;
64
65        for elem in self {
66            seq.serialize_element(elem)?;
67        }
68
69        seq.end()
70    }
71}
72
73#[cfg(test)]
74#[allow(clippy::unwrap_used)]
75mod tests {
76    const INTEGER_ARRAY_EXAMPLE: [u64; 4] = [1, 2, 3, 4];
77    use crate::{
78        Array,
79        sizes::{U4, U5},
80    };
81    use bincode::{
82        config,
83        error::DecodeError,
84        serde::{decode_from_slice, encode_to_vec},
85    };
86
87    #[test]
88    fn deserialize_integer_array() {
89        let serialized = encode_to_vec(INTEGER_ARRAY_EXAMPLE, config::standard()).unwrap();
90        let (deserialized, len): (Array<u64, U4>, usize) =
91            decode_from_slice(&serialized, config::standard()).unwrap();
92
93        assert_eq!(deserialized, INTEGER_ARRAY_EXAMPLE);
94        assert_eq!(len, serialized.len());
95    }
96
97    #[test]
98    fn deserialize_too_short() {
99        let serialized = encode_to_vec(INTEGER_ARRAY_EXAMPLE, config::standard()).unwrap();
100        let deserialized: Result<(Array<u8, U5>, usize), DecodeError> =
101            decode_from_slice(&serialized, config::standard());
102
103        // TODO(tarcieri): check for more specific error type
104        assert!(deserialized.is_err())
105    }
106
107    #[test]
108    fn serialize_integer_array() {
109        let example: Array<u64, U4> = Array(INTEGER_ARRAY_EXAMPLE);
110        let serialized = encode_to_vec(example, config::standard()).unwrap();
111        let (deserialized, len): (Array<u64, U4>, usize) =
112            decode_from_slice(&serialized, config::standard()).unwrap();
113
114        assert_eq!(example, deserialized);
115        assert_eq!(len, serialized.len());
116    }
117}