rune_alloc/serde/
de.rs

1use core::fmt;
2use core::marker::PhantomData;
3
4use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
5
6use crate::boxed::Box;
7use crate::vec::Vec;
8
9mod size_hint {
10    use core::cmp;
11    use core::mem;
12
13    pub fn cautious<Element>(hint: Option<usize>) -> usize {
14        const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
15
16        if mem::size_of::<Element>() == 0 {
17            0
18        } else {
19            cmp::min(
20                hint.unwrap_or(0),
21                MAX_PREALLOC_BYTES / mem::size_of::<Element>(),
22            )
23        }
24    }
25}
26
27mod seed {
28    use serde::de::{Deserialize, DeserializeSeed, Deserializer};
29
30    /// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
31    ///
32    /// Wraps a mutable reference and calls deserialize_in_place on it.
33    pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
34
35    impl<'de, T> DeserializeSeed<'de> for InPlaceSeed<'_, T>
36    where
37        T: Deserialize<'de>,
38    {
39        type Value = ();
40        fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
41        where
42            D: Deserializer<'de>,
43        {
44            T::deserialize_in_place(deserializer, self.0)
45        }
46    }
47}
48
49macro_rules! forwarded_impl {
50    (
51        $(#[doc = $doc:tt])*
52        <$($id:ident),*>, $ty:ty, $func:expr
53    ) => {
54        $(#[doc = $doc])*
55        impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
56            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57            where
58                D: Deserializer<'de>,
59            {
60                let value = Deserialize::deserialize(deserializer)?;
61                $func(value).map_err(D::Error::custom)
62            }
63        }
64    }
65}
66
67#[cfg(any(feature = "std", feature = "alloc"))]
68forwarded_impl!(<T>, Box<T>, Box::try_new);
69
70impl<'de, T> Deserialize<'de> for Vec<T>
71where
72    T: Deserialize<'de>,
73{
74    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
75    where
76        D: Deserializer<'de>,
77    {
78        struct VecVisitor<T> {
79            marker: PhantomData<T>,
80        }
81
82        impl<'de, T> Visitor<'de> for VecVisitor<T>
83        where
84            T: Deserialize<'de>,
85        {
86            type Value = Vec<T>;
87
88            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
89                formatter.write_str("a sequence")
90            }
91
92            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
93            where
94                A: SeqAccess<'de>,
95            {
96                let capacity = size_hint::cautious::<T>(seq.size_hint());
97                let mut values = Vec::<T>::try_with_capacity(capacity).map_err(A::Error::custom)?;
98
99                while let Some(value) = seq.next_element()? {
100                    values.try_push(value).map_err(A::Error::custom)?;
101                }
102
103                Ok(values)
104            }
105        }
106
107        let visitor = VecVisitor {
108            marker: PhantomData,
109        };
110
111        deserializer.deserialize_seq(visitor)
112    }
113
114    fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
115    where
116        D: Deserializer<'de>,
117    {
118        struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec<T>);
119
120        impl<'de, T> Visitor<'de> for VecInPlaceVisitor<'_, T>
121        where
122            T: Deserialize<'de>,
123        {
124            type Value = ();
125
126            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
127                formatter.write_str("a sequence")
128            }
129
130            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
131            where
132                A: SeqAccess<'de>,
133            {
134                let hint = size_hint::cautious::<T>(seq.size_hint());
135
136                if let Some(additional) = hint.checked_sub(self.0.len()) {
137                    self.0.try_reserve(additional).map_err(A::Error::custom)?;
138                }
139
140                for i in 0..self.0.len() {
141                    let next = {
142                        let next_place = seed::InPlaceSeed(&mut self.0[i]);
143                        seq.next_element_seed(next_place)?
144                    };
145
146                    if next.is_none() {
147                        self.0.truncate(i);
148                        return Ok(());
149                    }
150                }
151
152                while let Some(value) = seq.next_element()? {
153                    self.0.try_push(value).map_err(A::Error::custom)?;
154                }
155
156                Ok(())
157            }
158        }
159
160        deserializer.deserialize_seq(VecInPlaceVisitor(place))
161    }
162}
163
164impl<'de, T> Deserialize<'de> for Box<[T]>
165where
166    T: Deserialize<'de>,
167{
168    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
169    where
170        D: Deserializer<'de>,
171    {
172        Vec::<T>::deserialize(deserializer)?
173            .try_into_boxed_slice()
174            .map_err(D::Error::custom)
175    }
176}