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#[derive(Debug, Clone, PartialEq)]
19pub enum Error {
20 MissingValue(&'static str),
22
23 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
73struct 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 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
291pub 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
303pub 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}