pix_engine/
serialize.rs

1//! Serialization/Deserialization modules.
2
3#[doc(hidden)]
4pub mod arrays {
5    //! `Serialize` and `Deserialize` implementation for const generic arrays.
6
7    use serde::{
8        de::{SeqAccess, Visitor},
9        ser::SerializeTuple,
10        Deserialize, Deserializer, Serialize, Serializer,
11    };
12    use std::{convert::TryInto, marker::PhantomData};
13
14    struct ArrayVisitor<T, const N: usize>(PhantomData<T>);
15
16    impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<T, N>
17    where
18        T: Deserialize<'de>,
19    {
20        type Value = [T; N];
21
22        fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23            formatter.write_str(&format!("an array of length {N}"))
24        }
25
26        #[inline]
27        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
28        where
29            A: SeqAccess<'de>,
30        {
31            // can be optimized using MaybeUninit
32            let mut data = Vec::with_capacity(N);
33            for _ in 0..N {
34                match (seq.next_element())? {
35                    Some(val) => data.push(val),
36                    None => return Err(serde::de::Error::invalid_length(N, &self)),
37                }
38            }
39            match data.try_into() {
40                Ok(arr) => Ok(arr),
41                Err(_) => unreachable!(),
42            }
43        }
44    }
45
46    /// Serialize a const generic array.
47    #[inline]
48    pub fn serialize<S: Serializer, T: Serialize, const N: usize>(
49        data: &[T; N],
50        ser: S,
51    ) -> Result<S::Ok, S::Error> {
52        let mut s = ser.serialize_tuple(N)?;
53        for item in data {
54            s.serialize_element(item)?;
55        }
56        s.end()
57    }
58
59    /// Deserialize a const generic array.
60    #[inline]
61    pub fn deserialize<'de, D, T, const N: usize>(deserializer: D) -> Result<[T; N], D::Error>
62    where
63        D: Deserializer<'de>,
64        T: Deserialize<'de>,
65    {
66        deserializer.deserialize_tuple(N, ArrayVisitor::<T, N>(PhantomData))
67    }
68}