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>(
97        self,
98        _name: &'static str,
99        visitor: V,
100    ) -> Result<V::Value, Self::Error>
101    where
102        V: serde::de::Visitor<'de>,
103    {
104        visitor.visit_newtype_struct(self)
105    }
106
107    serde::forward_to_deserialize_any! {
108        char str string unit seq option
109        bytes byte_buf map unit_struct tuple_struct
110        identifier tuple ignored_any enum
111        struct bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64
112    }
113}
114
115impl<'de> IntoDeserializer<'de, Error> for Val {
116    type Deserializer = Self;
117
118    fn into_deserializer(self) -> Self::Deserializer {
119        self
120    }
121}
122
123impl<'de> de::Deserializer<'de> for Val {
124    type Error = Error;
125
126    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
127    where
128        V: de::Visitor<'de>,
129    {
130        self.0
131            .value()
132            .deref()
133            .clone()
134            .into_deserializer()
135            .deserialize_any(visitor)
136    }
137
138    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
139    where
140        V: de::Visitor<'de>,
141    {
142        let mut values: Vec<_> = self
143            .0
144            .children()
145            .into_iter()
146            .take_while(|c| c.key().parse::<usize>().is_ok())
147            .map(|s| Val(s))
148            .collect();
149
150        // guarantee stable ordering by zero-based ordinal index; for example,
151        // Key:0
152        // Key:1
153        // Key:n
154        values.sort_by(|s1, s2| {
155            s1.0.key()
156                .parse::<usize>()
157                .unwrap()
158                .cmp(&s2.0.key().parse::<usize>().unwrap())
159        });
160
161        SeqDeserializer::new(values.into_iter()).deserialize_seq(visitor)
162    }
163
164    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
165    where
166        V: Visitor<'de>,
167    {
168        let values = self
169            .0
170            .children()
171            .into_iter()
172            .map(|section| (section.key().to_owned(), Val(section)));
173
174        MapDeserializer::new(values).deserialize_map(visitor)
175    }
176
177    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
178    where
179        V: de::Visitor<'de>,
180    {
181        visitor.visit_some(self)
182    }
183
184    forward_parsed_values! {
185        bool => deserialize_bool,
186        u8 => deserialize_u8,
187        u16 => deserialize_u16,
188        u32 => deserialize_u32,
189        u64 => deserialize_u64,
190        i8 => deserialize_i8,
191        i16 => deserialize_i16,
192        i32 => deserialize_i32,
193        i64 => deserialize_i64,
194        f32 => deserialize_f32,
195        f64 => deserialize_f64,
196    }
197
198    fn deserialize_newtype_struct<V>(
199        self,
200        _name: &'static str,
201        visitor: V,
202    ) -> Result<V::Value, Self::Error>
203    where
204        V: serde::de::Visitor<'de>,
205    {
206        visitor.visit_newtype_struct(self)
207    }
208
209    fn deserialize_struct<V>(
210        self,
211        _name: &'static str,
212        _fields: &'static [&'static str],
213        visitor: V,
214    ) -> Result<V::Value, Self::Error>
215    where
216        V: Visitor<'de>,
217    {
218        let config = self.0.deref();
219        let deserializer = Deserializer::new(config);
220        de::Deserializer::deserialize_any(deserializer, visitor)
221    }
222
223    fn deserialize_enum<V>(
224        self,
225        _name: &'static str,
226        _variants: &'static [&'static str],
227        visitor: V,
228    ) -> Result<V::Value, Self::Error>
229    where
230        V: de::Visitor<'de>,
231    {
232        visitor.visit_enum(self.0.value().deref().clone().into_deserializer())
233    }
234
235    serde::forward_to_deserialize_any! {
236        char str string unit
237        bytes byte_buf unit_struct tuple_struct
238        identifier tuple ignored_any
239    }
240}
241
242struct ConfigValues(IntoIter<Box<dyn ConfigurationSection>>);
243
244impl Iterator for ConfigValues {
245    type Item = (Key, Val);
246
247    fn next(&mut self) -> Option<Self::Item> {
248        self.0
249            .next()
250            .map(|section| (Key(section.key().to_owned()), Val(section)))
251    }
252}
253
254struct Deserializer<'de> {
255    inner: MapDeserializer<'de, ConfigValues, Error>,
256}
257
258impl<'de> Deserializer<'de> {
259    fn new(config: &dyn Configuration) -> Self {
260        Deserializer {
261            inner: MapDeserializer::new(ConfigValues(config.children().into_iter())),
262        }
263    }
264}
265
266impl<'de> de::Deserializer<'de> for Deserializer<'de> {
267    type Error = Error;
268
269    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
270    where
271        V: de::Visitor<'de>,
272    {
273        self.deserialize_map(visitor)
274    }
275
276    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
277    where
278        V: de::Visitor<'de>,
279    {
280        visitor.visit_map(self.inner)
281    }
282
283    serde::forward_to_deserialize_any! {
284        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
285        bytes byte_buf unit_struct tuple_struct
286        identifier tuple ignored_any option newtype_struct enum
287        struct
288    }
289}
290
291/// Deserializes a data structure from the specified configuration.
292///
293/// # Arguments
294///
295/// * `configuration` - The [`Configuration`](crate::Configuration) to deserialize
296pub fn from_config<'a, T>(configuration: &'a dyn Configuration) -> Result<T, Error>
297where
298    T: Deserialize<'a>,
299{
300    Ok(T::deserialize(Deserializer::new(configuration))?)
301}
302
303/// Deserializes the specified configuration to an existing data structure.
304///
305/// # Arguments
306///
307/// * `configuration` - The [`Configuration`](crate::Configuration) to deserialize
308pub fn bind_config<'a, T>(configuration: &'a dyn Configuration, data: &mut T) -> Result<(), Error>
309where
310    T: Deserialize<'a>,
311{
312    Ok(T::deserialize_in_place(
313        Deserializer::new(configuration),
314        data,
315    )?)
316}