serde_big_array_options/
lib.rs

1// Credit: https://github.com/rust-lang/rust/issues/54542#issuecomment-425238990
2
3use std::marker::PhantomData;
4
5use serde::{
6    de::{SeqAccess, Visitor},
7    ser::SerializeTuple,
8    Deserialize, Deserializer, Serialize, Serializer,
9};
10pub fn serialize<S: Serializer, T: Serialize, const N: usize>(
11    data: &[Option<T>; N],
12    ser: S,
13) -> Result<S::Ok, S::Error> {
14    let mut s = ser.serialize_tuple(N)?;
15    for item in data {
16        s.serialize_element(item)?;
17    }
18    s.end()
19}
20
21struct ArrayVisitor<T, const N: usize>(PhantomData<Option<T>>);
22
23impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<Option<T>, N>
24where
25    T: Deserialize<'de> + Copy,
26{
27    type Value = [Option<T>; N];
28
29    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
30        formatter.write_str(&format!("an array of length {}", N))
31    }
32
33    #[inline]
34    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
35    where
36        A: SeqAccess<'de>,
37    {
38        let mut buf = [None; N];
39        for i in 0..N {
40            match (seq.next_element())? {
41                v @ Some(_) => buf[i] = v,
42                None => break,
43            }
44        }
45        Ok(buf)
46    }
47}
48pub fn deserialize<'de, D, T, const N: usize>(deserializer: D) -> Result<[Option<T>; N], D::Error>
49where
50    D: Deserializer<'de>,
51    T: Deserialize<'de> + Copy,
52{
53    deserializer.deserialize_tuple(N, ArrayVisitor::<Option<T>, N>(PhantomData))
54}