1use std::collections::VecDeque;
2use std::iter::Enumerate;
3
4use serde::de;
5
6use crate::config::Config;
7use crate::errors::{ConfigError, Result, Unexpected};
8use crate::map::Map;
9use crate::value::{Table, Value, ValueKind};
10
11macro_rules! try_convert_number {
12 (signed, $self:expr, $size:literal) => {{
13 let num = $self.into_int()?;
14 num.try_into().map_err(|_| {
15 ConfigError::invalid_type(
16 None,
17 Unexpected::I64(num),
18 concat!("an signed ", $size, " bit integer"),
19 )
20 })?
21 }};
22
23 (unsigned, $self:expr, $size:literal) => {{
24 let num = $self.into_uint()?;
25 num.try_into().map_err(|_| {
26 ConfigError::invalid_type(
27 None,
28 Unexpected::U64(num),
29 concat!("an unsigned ", $size, " bit integer"),
30 )
31 })?
32 }};
33}
34
35impl<'de> de::Deserializer<'de> for Value {
36 type Error = ConfigError;
37
38 #[inline]
39 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
40 where
41 V: de::Visitor<'de>,
42 {
43 match self.kind {
45 ValueKind::Nil => visitor.visit_unit(),
46 ValueKind::I64(i) => visitor.visit_i64(i),
47 ValueKind::I128(i) => visitor.visit_i128(i),
48 ValueKind::U64(i) => visitor.visit_u64(i),
49 ValueKind::U128(i) => visitor.visit_u128(i),
50 ValueKind::Boolean(b) => visitor.visit_bool(b),
51 ValueKind::Float(f) => visitor.visit_f64(f),
52 ValueKind::String(s) => visitor.visit_string(s),
53 ValueKind::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
54 ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map)),
55 }
56 }
57
58 #[inline]
59 fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
60 visitor.visit_bool(self.into_bool()?)
61 }
62
63 #[inline]
64 fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
65 let num = try_convert_number!(signed, self, "8");
66 visitor.visit_i8(num)
67 }
68
69 #[inline]
70 fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
71 let num = try_convert_number!(signed, self, "16");
72 visitor.visit_i16(num)
73 }
74
75 #[inline]
76 fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
77 let num = try_convert_number!(signed, self, "32");
78 visitor.visit_i32(num)
79 }
80
81 #[inline]
82 fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
83 let num = try_convert_number!(signed, self, "64");
84 visitor.visit_i64(num)
85 }
86
87 #[inline]
88 fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
89 let num = try_convert_number!(unsigned, self, "8");
90 visitor.visit_u8(num)
91 }
92
93 #[inline]
94 fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
95 let num = try_convert_number!(unsigned, self, "16");
96 visitor.visit_u16(num)
97 }
98
99 #[inline]
100 fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
101 let num = try_convert_number!(unsigned, self, "32");
102 visitor.visit_u32(num)
103 }
104
105 #[inline]
106 fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
107 let num = try_convert_number!(unsigned, self, "u64");
108 visitor.visit_u64(num)
109 }
110
111 #[inline]
112 fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
113 visitor.visit_f32(self.into_float()? as f32)
114 }
115
116 #[inline]
117 fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
118 visitor.visit_f64(self.into_float()?)
119 }
120
121 #[inline]
122 fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
123 visitor.visit_string(self.into_string()?)
124 }
125
126 #[inline]
127 fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
128 visitor.visit_string(self.into_string()?)
129 }
130
131 #[inline]
132 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
133 where
134 V: de::Visitor<'de>,
135 {
136 match self.kind {
138 ValueKind::Nil => visitor.visit_none(),
139 _ => visitor.visit_some(self),
140 }
141 }
142
143 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
144 where
145 V: de::Visitor<'de>,
146 {
147 visitor.visit_newtype_struct(self)
148 }
149
150 fn deserialize_enum<V>(
151 self,
152 name: &'static str,
153 variants: &'static [&'static str],
154 visitor: V,
155 ) -> Result<V::Value>
156 where
157 V: de::Visitor<'de>,
158 {
159 visitor.visit_enum(EnumAccess { value: self, name, variants })
160 }
161
162 serde::forward_to_deserialize_any! {
163 char seq
164 bytes byte_buf map struct unit
165 identifier ignored_any unit_struct tuple_struct tuple
166 }
167}
168
169struct StrDeserializer<'a>(&'a str);
170
171impl<'de, 'a> de::Deserializer<'de> for StrDeserializer<'a> {
172 type Error = ConfigError;
173
174 #[inline]
175 fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
176 visitor.visit_str(self.0)
177 }
178
179 serde::forward_to_deserialize_any! {
180 bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
181 bytes byte_buf map struct unit enum newtype_struct
182 identifier ignored_any unit_struct tuple_struct tuple option
183 }
184}
185
186struct SeqAccess {
187 elements: Enumerate<::std::vec::IntoIter<Value>>,
188}
189
190impl SeqAccess {
191 fn new(elements: Vec<Value>) -> Self {
192 Self { elements: elements.into_iter().enumerate() }
193 }
194}
195
196impl<'de> de::SeqAccess<'de> for SeqAccess {
197 type Error = ConfigError;
198
199 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
200 where
201 T: de::DeserializeSeed<'de>,
202 {
203 match self.elements.next() {
204 Some((idx, value)) => seed.deserialize(value).map(Some).map_err(|e| e.prepend_index(idx)),
205 None => Ok(None),
206 }
207 }
208
209 fn size_hint(&self) -> Option<usize> {
210 match self.elements.size_hint() {
211 (lower, Some(upper)) if lower == upper => Some(upper),
212 _ => None,
213 }
214 }
215}
216
217struct MapAccess {
218 elements: VecDeque<(String, Value)>,
219}
220
221impl MapAccess {
222 fn new(table: Map<String, Value>) -> Self {
223 Self { elements: table.into_iter().collect() }
224 }
225}
226
227impl<'de> de::MapAccess<'de> for MapAccess {
228 type Error = ConfigError;
229
230 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
231 where
232 K: de::DeserializeSeed<'de>,
233 {
234 if let Some((key_s, _)) = self.elements.front() {
235 let key_de = Value::new(None, key_s as &str);
236 let key = de::DeserializeSeed::deserialize(seed, key_de)?;
237
238 Ok(Some(key))
239 } else {
240 Ok(None)
241 }
242 }
243
244 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
245 where
246 V: de::DeserializeSeed<'de>,
247 {
248 let (key, value) = self.elements.pop_front().unwrap();
249 de::DeserializeSeed::deserialize(seed, value).map_err(|e| e.prepend_key(&key))
250 }
251}
252
253struct EnumAccess {
254 value: Value,
255 name: &'static str,
256 variants: &'static [&'static str],
257}
258
259impl EnumAccess {
260 fn variant_deserializer(&self, name: &str) -> Result<StrDeserializer> {
261 self
262 .variants
263 .iter()
264 .find(|&&s| s.to_lowercase() == name.to_lowercase()) .map(|&s| StrDeserializer(s))
266 .ok_or_else(|| self.no_constructor_error(name))
267 }
268
269 fn table_deserializer(&self, table: &Table) -> Result<StrDeserializer> {
270 if table.len() == 1 {
271 self.variant_deserializer(table.iter().next().unwrap().0)
272 } else {
273 Err(self.structural_error())
274 }
275 }
276
277 fn no_constructor_error(&self, supposed_variant: &str) -> ConfigError {
278 ConfigError::Message(format!(
279 "enum {} does not have variant constructor {}",
280 self.name, supposed_variant
281 ))
282 }
283
284 fn structural_error(&self) -> ConfigError {
285 ConfigError::Message(format!(
286 "value of enum {} should be represented by either string or table with exactly one key",
287 self.name
288 ))
289 }
290}
291
292impl<'de> de::EnumAccess<'de> for EnumAccess {
293 type Error = ConfigError;
294 type Variant = Self;
295
296 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
297 where
298 V: de::DeserializeSeed<'de>,
299 {
300 let value = {
301 let deserializer = match self.value.kind {
302 ValueKind::String(ref s) => self.variant_deserializer(s),
303 ValueKind::Table(ref t) => self.table_deserializer(t),
304 _ => Err(self.structural_error()),
305 }?;
306 seed.deserialize(deserializer)?
307 };
308
309 Ok((value, self))
310 }
311}
312
313impl<'de> de::VariantAccess<'de> for EnumAccess {
314 type Error = ConfigError;
315
316 fn unit_variant(self) -> Result<()> {
317 Ok(())
318 }
319
320 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
321 where
322 T: de::DeserializeSeed<'de>,
323 {
324 match self.value.kind {
325 ValueKind::Table(t) => seed.deserialize(t.into_iter().next().unwrap().1),
326 _ => unreachable!(),
327 }
328 }
329
330 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
331 where
332 V: de::Visitor<'de>,
333 {
334 match self.value.kind {
335 ValueKind::Table(t) => {
336 de::Deserializer::deserialize_seq(t.into_iter().next().unwrap().1, visitor)
337 }
338 _ => unreachable!(),
339 }
340 }
341
342 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
343 where
344 V: de::Visitor<'de>,
345 {
346 match self.value.kind {
347 ValueKind::Table(t) => {
348 de::Deserializer::deserialize_map(t.into_iter().next().unwrap().1, visitor)
349 }
350 _ => unreachable!(),
351 }
352 }
353}
354
355macro_rules! config_deserialize_via_value { { $(
359 $method:ident $( ( $( $arg:ident: $argtype:ty ),* ) )? ;
360)* } => { $(
361 #[inline]
362 fn $method<V: de::Visitor<'de>>(
363 self,
364 $( $( $arg: $argtype, )* )?
365 visitor: V,
366 ) -> Result<V::Value> {
367 self.cache.$method( $( $( $arg, )* )? visitor)
368 }
369)* } }
370
371impl<'de> de::Deserializer<'de> for Config {
372 type Error = ConfigError;
373
374 config_deserialize_via_value! {
375 deserialize_any;
376 deserialize_bool;
377 deserialize_i8;
378 deserialize_i16;
379 deserialize_i32;
380 deserialize_i64;
381 deserialize_u8;
382 deserialize_u16;
383 deserialize_u32;
384 deserialize_u64;
385 deserialize_f32;
386 deserialize_f64;
387 deserialize_str;
388 deserialize_string;
389 deserialize_option;
390
391 deserialize_char;
392 deserialize_seq;
393 deserialize_bytes;
394 deserialize_byte_buf;
395 deserialize_map;
396 deserialize_unit;
397 deserialize_identifier;
398 deserialize_ignored_any;
399
400 deserialize_enum(name: &'static str, variants: &'static [&'static str]);
401 deserialize_unit_struct(name: &'static str);
402 deserialize_newtype_struct(name: &'static str);
403 deserialize_tuple(n: usize);
404 deserialize_tuple_struct(name: &'static str, n: usize);
405 deserialize_struct(name: &'static str, fields: &'static [&'static str]);
406 }
407}