storm_config/
de.rs

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    // Deserialize based on the underlying type
44    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 an explicit nil as None and everything else as Some
137    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()) // changing to lowercase will enable deserialization of lowercase values to enums
265      .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
355/// Define `$method`s, `deserialize_foo`, by forwarding to `Value`
356///
357/// `($arg: $argtype, ...)`, if supplied, are the formal arguments
358macro_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}