serde_jam/visitor/
fixed.rs

1//! Fixed-size byte array visitor
2
3use crate::{Vec, format};
4use core::fmt;
5use serde::de::{self, Error};
6
7/// Visitor for fixed-size byte arrays
8#[derive(Default)]
9pub struct FixedBytesVisitor<T: TryFrom<Vec<u8>>> {
10    _marker: core::marker::PhantomData<T>,
11}
12
13impl<T: TryFrom<Vec<u8>>> FixedBytesVisitor<T> {
14    /// Create a new fixed bytes visitor
15    pub fn new() -> Self {
16        Self {
17            _marker: core::marker::PhantomData,
18        }
19    }
20}
21
22impl<'v, T: TryFrom<Vec<u8>>> de::Visitor<'v> for FixedBytesVisitor<T> {
23    type Value = T;
24
25    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
26        formatter.write_str(&format!(
27            "a fixed-size byte array of {} bytes",
28            core::mem::size_of::<T>()
29        ))
30    }
31
32    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
33    where
34        A: de::SeqAccess<'v>,
35    {
36        let mut bytes = Vec::with_capacity(core::mem::size_of::<T>());
37        for _ in 0..core::mem::size_of::<T>() {
38            bytes.push(seq.next_element()?.unwrap_or_default());
39        }
40        T::try_from(bytes).map_err(|_| A::Error::custom("invalid bytes: {bytes:?}"))
41    }
42}
43
44impl<'v, T: TryFrom<Vec<u8>>> de::DeserializeSeed<'v> for FixedBytesVisitor<T> {
45    type Value = T;
46
47    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
48    where
49        D: de::Deserializer<'v>,
50    {
51        deserializer.deserialize_tuple(core::mem::size_of::<T>(), self)
52    }
53}