1use std::collections::BTreeMap;
2
3use serde::{
4 de::{self, IntoDeserializer as _, Visitor},
5 ser,
6};
7
8use crate::value::ConfigValue;
9
10#[derive(Debug)]
12pub struct DeserializeError(String);
13
14impl std::fmt::Display for DeserializeError {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 write!(f, "{}", self.0)
17 }
18}
19
20impl std::error::Error for DeserializeError {}
21
22impl de::Error for DeserializeError {
23 fn custom<T: std::fmt::Display>(msg: T) -> Self {
24 Self(msg.to_string())
25 }
26}
27
28impl ser::Error for DeserializeError {
29 fn custom<T: std::fmt::Display>(msg: T) -> Self {
30 Self(msg.to_string())
31 }
32}
33
34pub struct ConfigValueDeserializer(pub ConfigValue);
39
40type Result<T> = std::result::Result<T, DeserializeError>;
41
42impl<'de> de::Deserializer<'de> for ConfigValueDeserializer {
43 type Error = DeserializeError;
44
45 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
46 match self.0 {
47 ConfigValue::Null => visitor.visit_unit(),
48 ConfigValue::Bool(b) => visitor.visit_bool(b),
49 ConfigValue::Integer(i) => visitor.visit_i64(i),
50 ConfigValue::Float(f) => visitor.visit_f64(f),
51 ConfigValue::String(s) => visitor.visit_string(s),
52 ConfigValue::Array(arr) => visitor.visit_seq(SeqDeserializer(arr.into_iter())),
53 ConfigValue::Table(map) => visitor.visit_map(MapDeserializer::new(map)),
54 }
55 }
56
57 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
58 match self.0 {
59 ConfigValue::Null => visitor.visit_none(),
60 other => visitor.visit_some(Self(other)),
61 }
62 }
63
64 fn deserialize_newtype_struct<V: Visitor<'de>>(
65 self,
66 _name: &'static str,
67 visitor: V,
68 ) -> Result<V::Value> {
69 visitor.visit_newtype_struct(self)
70 }
71
72 fn deserialize_enum<V: Visitor<'de>>(
73 self,
74 _name: &'static str,
75 _variants: &'static [&'static str],
76 visitor: V,
77 ) -> Result<V::Value> {
78 match self.0 {
79 ConfigValue::String(s) => visitor.visit_enum(s.into_deserializer()),
80 ConfigValue::Table(mut map) if map.len() == 1 => {
81 let (variant, payload) = map.pop_first().expect("len == 1 checked");
82 visitor.visit_enum(EnumDeserializer { variant, payload })
83 }
84 other => Err(de::Error::invalid_type(
85 unexpected(&other),
86 &"string or single-key table for enum variant",
87 )),
88 }
89 }
90
91 serde::forward_to_deserialize_any! {
92 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
93 char str string bytes byte_buf
94 unit unit_struct
95 seq tuple tuple_struct
96 map struct
97 identifier ignored_any
98 }
99}
100
101fn unexpected(v: &ConfigValue) -> de::Unexpected<'_> {
102 match v {
103 ConfigValue::Null => de::Unexpected::Unit,
104 ConfigValue::Bool(b) => de::Unexpected::Bool(*b),
105 ConfigValue::Integer(i) => de::Unexpected::Signed(*i),
106 ConfigValue::Float(f) => de::Unexpected::Float(*f),
107 ConfigValue::String(s) => de::Unexpected::Str(s),
108 ConfigValue::Array(_) => de::Unexpected::Seq,
109 ConfigValue::Table(_) => de::Unexpected::Map,
110 }
111}
112
113struct SeqDeserializer(std::vec::IntoIter<ConfigValue>);
114
115impl<'de> de::SeqAccess<'de> for SeqDeserializer {
116 type Error = DeserializeError;
117
118 fn next_element_seed<T: de::DeserializeSeed<'de>>(
119 &mut self,
120 seed: T,
121 ) -> Result<Option<T::Value>> {
122 match self.0.next() {
123 Some(v) => seed.deserialize(ConfigValueDeserializer(v)).map(Some),
124 None => Ok(None),
125 }
126 }
127}
128
129struct MapDeserializer {
130 iter: std::collections::btree_map::IntoIter<String, ConfigValue>,
131 pending: Option<ConfigValue>,
132}
133
134impl MapDeserializer {
135 fn new(map: BTreeMap<String, ConfigValue>) -> Self {
136 Self {
137 iter: map.into_iter(),
138 pending: None,
139 }
140 }
141}
142
143impl<'de> de::MapAccess<'de> for MapDeserializer {
144 type Error = DeserializeError;
145
146 fn next_key_seed<K: de::DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
147 match self.iter.next() {
148 Some((k, v)) => {
149 self.pending = Some(v);
150 seed.deserialize(de::value::StringDeserializer::new(k))
151 .map(Some)
152 }
153 None => Ok(None),
154 }
155 }
156
157 fn next_value_seed<V: de::DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
158 let v = self.pending.take().expect("called after next_key_seed");
159 seed.deserialize(ConfigValueDeserializer(v))
160 }
161}
162
163struct EnumDeserializer {
164 variant: String,
165 payload: ConfigValue,
166}
167
168impl<'de> de::EnumAccess<'de> for EnumDeserializer {
169 type Error = DeserializeError;
170 type Variant = Self;
171
172 fn variant_seed<V: de::DeserializeSeed<'de>>(
173 self,
174 seed: V,
175 ) -> Result<(V::Value, Self::Variant)> {
176 let tag = seed.deserialize(de::value::StringDeserializer::new(self.variant.clone()))?;
177 Ok((tag, self))
178 }
179}
180
181impl<'de> de::VariantAccess<'de> for EnumDeserializer {
182 type Error = DeserializeError;
183
184 fn unit_variant(self) -> Result<()> {
185 Ok(())
186 }
187
188 fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
189 seed.deserialize(ConfigValueDeserializer(self.payload))
190 }
191
192 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
193 de::Deserializer::deserialize_seq(ConfigValueDeserializer(self.payload), visitor)
194 }
195
196 fn struct_variant<V: Visitor<'de>>(
197 self,
198 _fields: &'static [&'static str],
199 visitor: V,
200 ) -> Result<V::Value> {
201 de::Deserializer::deserialize_map(ConfigValueDeserializer(self.payload), visitor)
202 }
203}
204
205pub struct ConfigValueSerializer;
207
208pub fn to_config_value<T: serde::Serialize>(
214 value: &T,
215) -> std::result::Result<ConfigValue, DeserializeError> {
216 value.serialize(ConfigValueSerializer)
217}
218
219impl ser::Serializer for ConfigValueSerializer {
220 type Ok = ConfigValue;
221 type Error = DeserializeError;
222
223 type SerializeSeq = SeqSerializer;
224 type SerializeTuple = SeqSerializer;
225 type SerializeTupleStruct = SeqSerializer;
226 type SerializeTupleVariant = TupleVariantSerializer;
227 type SerializeMap = MapSerializer;
228 type SerializeStruct = MapSerializer;
229 type SerializeStructVariant = StructVariantSerializer;
230
231 fn serialize_bool(self, v: bool) -> Result<ConfigValue> {
232 Ok(ConfigValue::Bool(v))
233 }
234 fn serialize_i8(self, v: i8) -> Result<ConfigValue> {
235 Ok(ConfigValue::Integer(i64::from(v)))
236 }
237 fn serialize_i16(self, v: i16) -> Result<ConfigValue> {
238 Ok(ConfigValue::Integer(i64::from(v)))
239 }
240 fn serialize_i32(self, v: i32) -> Result<ConfigValue> {
241 Ok(ConfigValue::Integer(i64::from(v)))
242 }
243 fn serialize_i64(self, v: i64) -> Result<ConfigValue> {
244 Ok(ConfigValue::Integer(v))
245 }
246 fn serialize_i128(self, v: i128) -> Result<ConfigValue> {
247 i64::try_from(v)
248 .map(ConfigValue::Integer)
249 .map_err(ser::Error::custom)
250 }
251 fn serialize_u8(self, v: u8) -> Result<ConfigValue> {
252 Ok(ConfigValue::Integer(i64::from(v)))
253 }
254 fn serialize_u16(self, v: u16) -> Result<ConfigValue> {
255 Ok(ConfigValue::Integer(i64::from(v)))
256 }
257 fn serialize_u32(self, v: u32) -> Result<ConfigValue> {
258 Ok(ConfigValue::Integer(i64::from(v)))
259 }
260 fn serialize_u64(self, v: u64) -> Result<ConfigValue> {
261 i64::try_from(v)
262 .map(ConfigValue::Integer)
263 .map_err(ser::Error::custom)
264 }
265 fn serialize_u128(self, v: u128) -> Result<ConfigValue> {
266 i64::try_from(v)
267 .map(ConfigValue::Integer)
268 .map_err(ser::Error::custom)
269 }
270 fn serialize_f32(self, v: f32) -> Result<ConfigValue> {
271 Ok(ConfigValue::Float(f64::from(v)))
272 }
273 fn serialize_f64(self, v: f64) -> Result<ConfigValue> {
274 Ok(ConfigValue::Float(v))
275 }
276 fn serialize_char(self, v: char) -> Result<ConfigValue> {
277 Ok(ConfigValue::String(v.to_string()))
278 }
279 fn serialize_str(self, v: &str) -> Result<ConfigValue> {
280 Ok(ConfigValue::String(v.to_owned()))
281 }
282 fn serialize_bytes(self, v: &[u8]) -> Result<ConfigValue> {
283 Ok(ConfigValue::Array(
284 v.iter()
285 .map(|b| ConfigValue::Integer(i64::from(*b)))
286 .collect(),
287 ))
288 }
289 fn serialize_none(self) -> Result<ConfigValue> {
290 Ok(ConfigValue::Null)
291 }
292 fn serialize_some<T: serde::Serialize + ?Sized>(self, value: &T) -> Result<ConfigValue> {
293 value.serialize(self)
294 }
295 fn serialize_unit(self) -> Result<ConfigValue> {
296 Ok(ConfigValue::Null)
297 }
298 fn serialize_unit_struct(self, _name: &'static str) -> Result<ConfigValue> {
299 Ok(ConfigValue::Null)
300 }
301 fn serialize_unit_variant(
302 self,
303 _name: &'static str,
304 _index: u32,
305 variant: &'static str,
306 ) -> Result<ConfigValue> {
307 Ok(ConfigValue::String(variant.to_owned()))
308 }
309 fn serialize_newtype_struct<T: serde::Serialize + ?Sized>(
310 self,
311 _name: &'static str,
312 value: &T,
313 ) -> Result<ConfigValue> {
314 value.serialize(self)
315 }
316 fn serialize_newtype_variant<T: serde::Serialize + ?Sized>(
317 self,
318 _name: &'static str,
319 _index: u32,
320 variant: &'static str,
321 value: &T,
322 ) -> Result<ConfigValue> {
323 let mut map = BTreeMap::new();
324 map.insert(variant.to_owned(), value.serialize(Self)?);
325 Ok(ConfigValue::Table(map))
326 }
327 fn serialize_seq(self, len: Option<usize>) -> Result<SeqSerializer> {
328 Ok(SeqSerializer(Vec::with_capacity(len.unwrap_or(0))))
329 }
330 fn serialize_tuple(self, len: usize) -> Result<SeqSerializer> {
331 Ok(SeqSerializer(Vec::with_capacity(len)))
332 }
333 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqSerializer> {
334 Ok(SeqSerializer(Vec::with_capacity(len)))
335 }
336 fn serialize_tuple_variant(
337 self,
338 _name: &'static str,
339 _index: u32,
340 variant: &'static str,
341 len: usize,
342 ) -> Result<TupleVariantSerializer> {
343 Ok(TupleVariantSerializer {
344 variant: variant.to_owned(),
345 items: Vec::with_capacity(len),
346 })
347 }
348 fn serialize_map(self, _len: Option<usize>) -> Result<MapSerializer> {
349 Ok(MapSerializer::default())
350 }
351 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<MapSerializer> {
352 Ok(MapSerializer::default())
353 }
354 fn serialize_struct_variant(
355 self,
356 _name: &'static str,
357 _index: u32,
358 variant: &'static str,
359 _len: usize,
360 ) -> Result<StructVariantSerializer> {
361 Ok(StructVariantSerializer {
362 variant: variant.to_owned(),
363 fields: BTreeMap::new(),
364 })
365 }
366}
367
368pub struct SeqSerializer(Vec<ConfigValue>);
369
370impl ser::SerializeSeq for SeqSerializer {
371 type Ok = ConfigValue;
372 type Error = DeserializeError;
373 fn serialize_element<T: serde::Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
374 self.0.push(value.serialize(ConfigValueSerializer)?);
375 Ok(())
376 }
377 fn end(self) -> Result<ConfigValue> {
378 Ok(ConfigValue::Array(self.0))
379 }
380}
381impl ser::SerializeTuple for SeqSerializer {
382 type Ok = ConfigValue;
383 type Error = DeserializeError;
384 fn serialize_element<T: serde::Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
385 ser::SerializeSeq::serialize_element(self, value)
386 }
387 fn end(self) -> Result<ConfigValue> {
388 ser::SerializeSeq::end(self)
389 }
390}
391impl ser::SerializeTupleStruct for SeqSerializer {
392 type Ok = ConfigValue;
393 type Error = DeserializeError;
394 fn serialize_field<T: serde::Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
395 ser::SerializeSeq::serialize_element(self, value)
396 }
397 fn end(self) -> Result<ConfigValue> {
398 ser::SerializeSeq::end(self)
399 }
400}
401
402pub struct TupleVariantSerializer {
403 variant: String,
404 items: Vec<ConfigValue>,
405}
406impl ser::SerializeTupleVariant for TupleVariantSerializer {
407 type Ok = ConfigValue;
408 type Error = DeserializeError;
409 fn serialize_field<T: serde::Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
410 self.items.push(value.serialize(ConfigValueSerializer)?);
411 Ok(())
412 }
413 fn end(self) -> Result<ConfigValue> {
414 let mut map = BTreeMap::new();
415 map.insert(self.variant, ConfigValue::Array(self.items));
416 Ok(ConfigValue::Table(map))
417 }
418}
419
420#[derive(Default)]
421pub struct MapSerializer {
422 map: BTreeMap<String, ConfigValue>,
423 pending_key: Option<String>,
424}
425impl ser::SerializeMap for MapSerializer {
426 type Ok = ConfigValue;
427 type Error = DeserializeError;
428 fn serialize_key<T: serde::Serialize + ?Sized>(&mut self, key: &T) -> Result<()> {
429 let k = match key.serialize(ConfigValueSerializer)? {
430 ConfigValue::String(s) => s,
431 other => {
432 return Err(ser::Error::custom(format!(
433 "map key must be a string, got {other:?}"
434 )));
435 }
436 };
437 self.pending_key = Some(k);
438 Ok(())
439 }
440 fn serialize_value<T: serde::Serialize + ?Sized>(&mut self, value: &T) -> Result<()> {
441 let k = self
442 .pending_key
443 .take()
444 .expect("serialize_value called after serialize_key");
445 self.map.insert(k, value.serialize(ConfigValueSerializer)?);
446 Ok(())
447 }
448 fn end(self) -> Result<ConfigValue> {
449 Ok(ConfigValue::Table(self.map))
450 }
451}
452impl ser::SerializeStruct for MapSerializer {
453 type Ok = ConfigValue;
454 type Error = DeserializeError;
455 fn serialize_field<T: serde::Serialize + ?Sized>(
456 &mut self,
457 key: &'static str,
458 value: &T,
459 ) -> Result<()> {
460 self.map
461 .insert(key.to_owned(), value.serialize(ConfigValueSerializer)?);
462 Ok(())
463 }
464 fn end(self) -> Result<ConfigValue> {
465 Ok(ConfigValue::Table(self.map))
466 }
467}
468
469pub struct StructVariantSerializer {
470 variant: String,
471 fields: BTreeMap<String, ConfigValue>,
472}
473impl ser::SerializeStructVariant for StructVariantSerializer {
474 type Ok = ConfigValue;
475 type Error = DeserializeError;
476 fn serialize_field<T: serde::Serialize + ?Sized>(
477 &mut self,
478 key: &'static str,
479 value: &T,
480 ) -> Result<()> {
481 self.fields
482 .insert(key.to_owned(), value.serialize(ConfigValueSerializer)?);
483 Ok(())
484 }
485 fn end(self) -> Result<ConfigValue> {
486 let mut map = BTreeMap::new();
487 map.insert(self.variant, ConfigValue::Table(self.fields));
488 Ok(ConfigValue::Table(map))
489 }
490}