ez_jsonrpc/params/
from_positional_impl.rs

1use super::DeserializePositional;
2use serde::{de::Error as _, Deserialize};
3use std::fmt;
4
5macro_rules! ptr {
6    ($($ty:ty),* $(,)?) => {
7        $(
8            impl<'de, T> DeserializePositional<'de> for $ty where T: DeserializePositional<'de> {
9                fn de_positional<D: serde::de::SeqAccess<'de>>(
10                    deserializer: D,
11                ) -> Result<Self, D::Error>
12                {
13                    T::de_positional(deserializer).map(Into::into)
14                }
15            }
16        )*
17    };
18}
19
20ptr!(Box<T>, std::sync::Arc<T>, std::rc::Rc<T>);
21
22macro_rules! iter {
23    ($($ty:ty $(: $($bound:path)+)?),* $(,)?) => {
24        $(
25            impl<'de, T> DeserializePositional<'de> for $ty
26            where
27                T: Deserialize<'de> $($(+ $bound)*)?,
28            {
29                fn de_positional<D: serde::de::SeqAccess<'de>>(
30                    deserializer: D,
31                ) -> Result<Self, D::Error>
32                {
33                    Self::deserialize(serde::de::value::SeqAccessDeserializer::new(deserializer))
34                }
35            }
36        )*
37    };
38}
39
40iter!(
41    Vec<T>,
42    Box<[T]>,
43    std::collections::LinkedList<T>,
44    std::collections::VecDeque<T>,
45    std::collections::BinaryHeap<T>: Ord,
46    std::collections::BTreeSet<T>: Ord,
47    std::collections::HashSet<T>: Eq std::hash::Hash,
48);
49
50macro_rules! tuple {
51    ($($ty:ident),* $(,)?) => {
52        impl<'de, $($ty),*> DeserializePositional<'de> for ($($ty,)*)
53        where
54        $($ty: Deserialize<'de>),*
55        {
56            fn de_positional<D: serde::de::SeqAccess<'de>>(
57                mut deserializer: D,
58            ) -> Result<Self, D::Error>
59            {
60                struct Expected;
61                impl serde::de::Expected for Expected {
62                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63                        const ARITY: usize = <[()]>::len(&[$({stringify!($ty);},)*]);
64                        f.write_fmt(format_args!("a sequence of length {}", ARITY))
65                    }
66                }
67                #[allow(unused_mut)]
68                let mut ct = 0;
69                let ret = ($({
70                    match deserializer.next_element::<$ty>()? {
71                        Some(it) => { ct +=1; it },
72                        None => return Err(D::Error::invalid_length(ct, &Expected)),
73                    }
74                },)*);
75                let Ok(None) = deserializer.next_element::<serde::de::IgnoredAny>() else {
76                    return Err(D::Error::invalid_length(ct + 1, &Expected))
77                };
78                Ok(ret)
79            }
80        }
81    };
82}
83
84super::for_tuples!(tuple);