Skip to main content

config/
de.rs

1use crate::{Configuration, ConfigurationSection};
2use serde::{
3    de::{
4        self,
5        value::{MapDeserializer, SeqDeserializer},
6        IntoDeserializer, Visitor,
7    },
8    Deserialize,
9};
10use std::{
11    fmt::{self, Display, Formatter},
12    iter::IntoIterator,
13    ops::Deref,
14    vec::IntoIter,
15};
16
17/// Represents the deserialization errors that can occur.
18#[derive(Debug, Clone, PartialEq)]
19pub enum Error {
20    /// Indicates a value is missing
21    MissingValue(&'static str),
22
23    /// Indicates a custom error message
24    Custom(String),
25}
26
27impl de::Error for Error {
28    fn custom<T: Display>(message: T) -> Self {
29        Error::Custom(message.to_string())
30    }
31
32    fn missing_field(field: &'static str) -> Error {
33        Error::MissingValue(field)
34    }
35}
36
37impl Display for Error {
38    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
39        match *self {
40            Error::MissingValue(field) => {
41                formatter.write_str("missing value for field ")?;
42                formatter.write_str(field)
43            }
44            Error::Custom(ref msg) => formatter.write_str(msg),
45        }
46    }
47}
48
49impl std::error::Error for Error {
50    fn description(&self) -> &str {
51        match *self {
52            Error::MissingValue(_) => "missing value",
53            Error::Custom(_) => "custom error",
54        }
55    }
56}
57
58macro_rules! forward_parsed_values {
59    ($($ty:ident => $method:ident,)*) => {
60        $(
61            fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
62                where V: de::Visitor<'de>
63            {
64                match self.0.value().parse::<$ty>() {
65                    Ok(val) => val.into_deserializer().$method(visitor),
66                    Err(e) => Err(de::Error::custom(format_args!("{} while parsing value '{}' provided by {}", e, self.0.value(), self.0.key())))
67                }
68            }
69        )*
70    }
71}
72
73// configuration is a key/value pair mapping of String: String or String: Vec<String>; however,
74// we need a surrogate type to implement forward the deserialization on to underlying primitives
75struct Key(String);
76struct Val(Box<dyn ConfigurationSection>);
77
78impl<'de> IntoDeserializer<'de, Error> for Key {
79    type Deserializer = Self;
80
81    fn into_deserializer(self) -> Self::Deserializer {
82        self
83    }
84}
85
86impl<'de> de::Deserializer<'de> for Key {
87    type Error = Error;
88
89    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
90    where
91        V: de::Visitor<'de>,
92    {
93        self.0.into_deserializer().deserialize_any(visitor)
94    }
95
96    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
97    where
98        V: serde::de::Visitor<'de>,
99    {
100        visitor.visit_newtype_struct(self)
101    }
102
103    serde::forward_to_deserialize_any! {
104        char str string unit seq option
105        bytes byte_buf map unit_struct tuple_struct
106        identifier tuple ignored_any enum
107        struct bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64
108    }
109}
110
111impl<'de> IntoDeserializer<'de, Error> for Val {
112    type Deserializer = Self;
113
114    fn into_deserializer(self) -> Self::Deserializer {
115        self
116    }
117}
118
119impl<'de> de::Deserializer<'de> for Val {
120    type Error = Error;
121
122    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
123    where
124        V: de::Visitor<'de>,
125    {
126        self.0
127            .value()
128            .deref()
129            .clone()
130            .into_deserializer()
131            .deserialize_any(visitor)
132    }
133
134    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
135    where
136        V: de::Visitor<'de>,
137    {
138        let mut values: Vec<_> = self
139            .0
140            .children()
141            .into_iter()
142            .take_while(|c| c.key().parse::<usize>().is_ok())
143            .map(Val)
144            .collect();
145
146        // guarantee stable ordering by zero-based ordinal index; for example,
147        // Key:0
148        // Key:1
149        // Key:n
150        values.sort_by(|s1, s2| {
151            s1.0.key()
152                .parse::<usize>()
153                .unwrap()
154                .cmp(&s2.0.key().parse::<usize>().unwrap())
155        });
156
157        SeqDeserializer::new(values.into_iter()).deserialize_seq(visitor)
158    }
159
160    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
161    where
162        V: Visitor<'de>,
163    {
164        let values = self
165            .0
166            .children()
167            .into_iter()
168            .map(|section| (section.key().to_owned(), Val(section)));
169
170        MapDeserializer::new(values).deserialize_map(visitor)
171    }
172
173    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
174    where
175        V: de::Visitor<'de>,
176    {
177        visitor.visit_some(self)
178    }
179
180    forward_parsed_values! {
181        bool => deserialize_bool,
182        u8 => deserialize_u8,
183        u16 => deserialize_u16,
184        u32 => deserialize_u32,
185        u64 => deserialize_u64,
186        i8 => deserialize_i8,
187        i16 => deserialize_i16,
188        i32 => deserialize_i32,
189        i64 => deserialize_i64,
190        f32 => deserialize_f32,
191        f64 => deserialize_f64,
192    }
193
194    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
195    where
196        V: serde::de::Visitor<'de>,
197    {
198        visitor.visit_newtype_struct(self)
199    }
200
201    fn deserialize_struct<V>(
202        self,
203        _name: &'static str,
204        _fields: &'static [&'static str],
205        visitor: V,
206    ) -> Result<V::Value, Self::Error>
207    where
208        V: Visitor<'de>,
209    {
210        let config = self.0.deref();
211        let deserializer = Deserializer::new(config);
212        de::Deserializer::deserialize_any(deserializer, visitor)
213    }
214
215    fn deserialize_enum<V>(
216        self,
217        _name: &'static str,
218        _variants: &'static [&'static str],
219        visitor: V,
220    ) -> Result<V::Value, Self::Error>
221    where
222        V: de::Visitor<'de>,
223    {
224        visitor.visit_enum(self.0.value().deref().clone().into_deserializer())
225    }
226
227    serde::forward_to_deserialize_any! {
228        char str string unit
229        bytes byte_buf unit_struct tuple_struct
230        identifier tuple ignored_any
231    }
232}
233
234struct ConfigValues(IntoIter<Box<dyn ConfigurationSection>>);
235
236impl Iterator for ConfigValues {
237    type Item = (Key, Val);
238
239    fn next(&mut self) -> Option<Self::Item> {
240        self.0
241            .next()
242            .map(|section| (Key(section.key().to_owned()), Val(section)))
243    }
244}
245
246struct Deserializer<'de> {
247    inner: MapDeserializer<'de, ConfigValues, Error>,
248}
249
250impl<'de> Deserializer<'de> {
251    fn new(config: &dyn Configuration) -> Self {
252        Deserializer {
253            inner: MapDeserializer::new(ConfigValues(config.children().into_iter())),
254        }
255    }
256}
257
258impl<'de> de::Deserializer<'de> for Deserializer<'de> {
259    type Error = Error;
260
261    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
262    where
263        V: de::Visitor<'de>,
264    {
265        self.deserialize_map(visitor)
266    }
267
268    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
269    where
270        V: de::Visitor<'de>,
271    {
272        visitor.visit_map(self.inner)
273    }
274
275    serde::forward_to_deserialize_any! {
276        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
277        bytes byte_buf unit_struct tuple_struct
278        identifier tuple ignored_any option newtype_struct enum
279        struct
280    }
281}
282
283/// Deserializes a data structure from the specified configuration.
284///
285/// # Arguments
286///
287/// * `configuration` - The [`Configuration`](crate::Configuration) to deserialize
288pub fn from_config<'a, T>(configuration: &'a dyn Configuration) -> Result<T, Error>
289where
290    T: Deserialize<'a>,
291{
292    T::deserialize(Deserializer::new(configuration))
293}
294
295/// Deserializes the specified configuration to an existing data structure.
296///
297/// # Arguments
298///
299/// * `configuration` - The [`Configuration`](crate::Configuration) to deserialize
300pub fn bind_config<'a, T>(configuration: &'a dyn Configuration, data: &mut T) -> Result<(), Error>
301where
302    T: Deserialize<'a>,
303{
304    T::deserialize_in_place(Deserializer::new(configuration), data)
305}