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>(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 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
283pub 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
295pub 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}