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 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}