Skip to main content

config/
ser.rs

1use std::fmt::Display;
2use std::fmt::Write as _;
3
4use serde_core::ser;
5
6use crate::Config;
7use crate::error::{ConfigError, Result};
8use crate::value::{Value, ValueKind};
9
10#[derive(Default, Debug)]
11pub(crate) struct ConfigSerializer {
12    keys: Vec<SerKey>,
13    pub output: Config,
14}
15
16#[derive(Debug)]
17enum SerKey {
18    Named(String),
19    Seq(usize),
20}
21
22/// An uninhabited type: no values like this can ever exist!
23pub(crate) enum Unreachable {}
24
25/// Serializer for numbered sequences
26///
27/// This wrapper is present when we are outputting a sequence (numbered indices).
28/// Making this a separate type centralises the handling of sequences
29/// and ensures we don't have any call sites for `ser::SerializeSeq::serialize_element`
30/// that don't do the necessary work of `SeqSerializer::new`.
31///
32/// Existence of this wrapper implies that `.0.keys.last()` is
33/// `Some(SerKey::Seq(next_index))`.
34pub(crate) struct SeqSerializer<'a>(&'a mut ConfigSerializer);
35
36impl ConfigSerializer {
37    fn serialize_primitive<T>(&mut self, value: T) -> Result<()>
38    where
39        T: Into<Value> + Display,
40    {
41        // At some future point we could perhaps retain a cursor into the output `Config`,
42        // rather than reifying the whole thing into a single string with `make_full_key`
43        // and passing that whole path to the `set` method.
44        //
45        // That would be marginally more performant, but more fiddly.
46        let key = self.make_full_key()?;
47
48        self.output.set(&key, value.into())?;
49        Ok(())
50    }
51
52    fn make_full_key(&self) -> Result<String> {
53        let mut keys = self.keys.iter();
54
55        let mut whole = match keys.next() {
56            Some(SerKey::Named(s)) => s.clone(),
57            _ => return Err(ConfigError::Message("top level is not a struct".to_owned())),
58        };
59
60        for k in keys {
61            match k {
62                SerKey::Named(s) => write!(whole, ".{s}"),
63                SerKey::Seq(i) => write!(whole, "[{i}]"),
64            }
65            .expect("write! to a string failed");
66        }
67
68        Ok(whole)
69    }
70
71    fn push_key(&mut self, key: &str) {
72        self.keys.push(SerKey::Named(key.to_owned()));
73    }
74
75    fn pop_key(&mut self) {
76        self.keys.pop();
77    }
78}
79
80impl<'a> ser::Serializer for &'a mut ConfigSerializer {
81    type Ok = ();
82    type Error = ConfigError;
83    type SerializeSeq = SeqSerializer<'a>;
84    type SerializeTuple = SeqSerializer<'a>;
85    type SerializeTupleStruct = SeqSerializer<'a>;
86    type SerializeTupleVariant = SeqSerializer<'a>;
87    type SerializeMap = Self;
88    type SerializeStruct = Self;
89    type SerializeStructVariant = Self;
90
91    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
92        self.serialize_primitive(v)
93    }
94
95    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
96        self.serialize_i64(v.into())
97    }
98
99    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
100        self.serialize_i64(v.into())
101    }
102
103    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
104        self.serialize_i64(v.into())
105    }
106
107    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
108        self.serialize_primitive(v)
109    }
110
111    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
112        self.serialize_u64(v.into())
113    }
114
115    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
116        self.serialize_u64(v.into())
117    }
118
119    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
120        self.serialize_u64(v.into())
121    }
122
123    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
124        self.serialize_primitive(v)
125    }
126
127    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
128        self.serialize_f64(v.into())
129    }
130
131    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
132        self.serialize_primitive(v)
133    }
134
135    fn serialize_char(self, v: char) -> Result<Self::Ok> {
136        self.serialize_primitive(v.to_string())
137    }
138
139    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
140        self.serialize_primitive(v.to_owned())
141    }
142
143    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
144        use serde_core::ser::SerializeSeq;
145        let mut seq = self.serialize_seq(Some(v.len()))?;
146        for byte in v {
147            seq.serialize_element(byte)?;
148        }
149        seq.end();
150        Ok(())
151    }
152
153    fn serialize_none(self) -> Result<Self::Ok> {
154        self.serialize_unit()
155    }
156
157    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
158    where
159        T: ?Sized + ser::Serialize,
160    {
161        value.serialize(self)
162    }
163
164    fn serialize_unit(self) -> Result<Self::Ok> {
165        self.serialize_primitive(Value::from(ValueKind::Nil))
166    }
167
168    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
169        self.serialize_unit()
170    }
171
172    fn serialize_unit_variant(
173        self,
174        _name: &'static str,
175        _variant_index: u32,
176        variant: &'static str,
177    ) -> Result<Self::Ok> {
178        self.serialize_str(variant)
179    }
180
181    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
182    where
183        T: ?Sized + ser::Serialize,
184    {
185        value.serialize(self)
186    }
187
188    fn serialize_newtype_variant<T>(
189        self,
190        _name: &'static str,
191        _variant_index: u32,
192        variant: &'static str,
193        value: &T,
194    ) -> Result<Self::Ok>
195    where
196        T: ?Sized + ser::Serialize,
197    {
198        self.push_key(variant);
199        value.serialize(&mut *self)?;
200        self.pop_key();
201        Ok(())
202    }
203
204    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
205        SeqSerializer::new(self)
206    }
207
208    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
209        self.serialize_seq(Some(len))
210    }
211
212    fn serialize_tuple_struct(
213        self,
214        _name: &'static str,
215        len: usize,
216    ) -> Result<Self::SerializeTupleStruct> {
217        self.serialize_seq(Some(len))
218    }
219
220    fn serialize_tuple_variant(
221        self,
222        _name: &'static str,
223        _variant_index: u32,
224        variant: &'static str,
225        len: usize,
226    ) -> Result<Self::SerializeTupleVariant> {
227        self.push_key(variant);
228        self.serialize_seq(Some(len))
229    }
230
231    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
232        Ok(self)
233    }
234
235    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
236        self.serialize_map(Some(len))
237    }
238
239    fn serialize_struct_variant(
240        self,
241        _name: &'static str,
242        _variant_index: u32,
243        variant: &'static str,
244        _len: usize,
245    ) -> Result<Self::SerializeStructVariant> {
246        self.push_key(variant);
247        Ok(self)
248    }
249}
250
251impl<'a> SeqSerializer<'a> {
252    fn new(inner: &'a mut ConfigSerializer) -> Result<Self> {
253        inner.keys.push(SerKey::Seq(0));
254
255        Ok(SeqSerializer(inner))
256    }
257
258    fn end(self) -> &'a mut ConfigSerializer {
259        // This ought to be Some(SerKey::Seq(..)) but we don't want to panic if we are buggy
260        let _: Option<SerKey> = self.0.keys.pop();
261        self.0
262    }
263}
264
265impl ser::SerializeSeq for SeqSerializer<'_> {
266    type Ok = ();
267    type Error = ConfigError;
268
269    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
270    where
271        T: ?Sized + ser::Serialize,
272    {
273        value.serialize(&mut *(self.0))?;
274        match self.0.keys.last_mut() {
275            Some(SerKey::Seq(i)) => *i += 1,
276            _ => {
277                return Err(ConfigError::Message(
278                    "config-rs internal error (ser._element but last not Seq!".to_owned(),
279                ));
280            }
281        };
282        Ok(())
283    }
284
285    fn end(self) -> Result<Self::Ok> {
286        self.end();
287        Ok(())
288    }
289}
290
291impl ser::SerializeTuple for SeqSerializer<'_> {
292    type Ok = ();
293    type Error = ConfigError;
294
295    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
296    where
297        T: ?Sized + ser::Serialize,
298    {
299        ser::SerializeSeq::serialize_element(self, value)
300    }
301
302    fn end(self) -> Result<Self::Ok> {
303        ser::SerializeSeq::end(self)
304    }
305}
306
307impl ser::SerializeTupleStruct for SeqSerializer<'_> {
308    type Ok = ();
309    type Error = ConfigError;
310
311    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
312    where
313        T: ?Sized + ser::Serialize,
314    {
315        ser::SerializeSeq::serialize_element(self, value)
316    }
317
318    fn end(self) -> Result<Self::Ok> {
319        ser::SerializeSeq::end(self)
320    }
321}
322
323impl ser::SerializeTupleVariant for SeqSerializer<'_> {
324    type Ok = ();
325    type Error = ConfigError;
326
327    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
328    where
329        T: ?Sized + ser::Serialize,
330    {
331        ser::SerializeSeq::serialize_element(self, value)
332    }
333
334    fn end(self) -> Result<Self::Ok> {
335        let inner = self.end();
336        inner.pop_key();
337        Ok(())
338    }
339}
340
341impl ser::SerializeMap for &mut ConfigSerializer {
342    type Ok = ();
343    type Error = ConfigError;
344
345    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
346    where
347        T: ?Sized + ser::Serialize,
348    {
349        let key_serializer = StringKeySerializer;
350        let key = key.serialize(key_serializer)?;
351        self.push_key(&key);
352        Ok(())
353    }
354
355    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
356    where
357        T: ?Sized + ser::Serialize,
358    {
359        value.serialize(&mut **self)?;
360        self.pop_key();
361        Ok(())
362    }
363
364    fn end(self) -> Result<Self::Ok> {
365        Ok(())
366    }
367}
368
369impl ser::SerializeStruct for &mut ConfigSerializer {
370    type Ok = ();
371    type Error = ConfigError;
372
373    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
374    where
375        T: ?Sized + ser::Serialize,
376    {
377        self.push_key(key);
378        value.serialize(&mut **self)?;
379        self.pop_key();
380        Ok(())
381    }
382
383    fn end(self) -> Result<Self::Ok> {
384        Ok(())
385    }
386}
387
388impl ser::SerializeStructVariant for &mut ConfigSerializer {
389    type Ok = ();
390    type Error = ConfigError;
391
392    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
393    where
394        T: ?Sized + ser::Serialize,
395    {
396        self.push_key(key);
397        value.serialize(&mut **self)?;
398        self.pop_key();
399        Ok(())
400    }
401
402    fn end(self) -> Result<Self::Ok> {
403        self.pop_key();
404        Ok(())
405    }
406}
407
408pub(crate) struct StringKeySerializer;
409
410/// Define `$emthod`, `serialize_foo`, taking `$type` and serialising it via [`Display`]
411macro_rules! string_serialize_via_display { { $method:ident, $type:ty } => {
412    fn $method(self, v: $type) -> Result<Self::Ok> {
413        #[allow(clippy::str_to_string)]
414        Ok(v.to_string())
415    }
416} }
417
418impl ser::Serializer for StringKeySerializer {
419    type Ok = String;
420    type Error = ConfigError;
421    type SerializeSeq = Unreachable;
422    type SerializeTuple = Unreachable;
423    type SerializeTupleStruct = Unreachable;
424    type SerializeTupleVariant = Unreachable;
425    type SerializeMap = Unreachable;
426    type SerializeStruct = Unreachable;
427    type SerializeStructVariant = Unreachable;
428
429    string_serialize_via_display!(serialize_bool, bool);
430    string_serialize_via_display!(serialize_i8, i8);
431    string_serialize_via_display!(serialize_i16, i16);
432    string_serialize_via_display!(serialize_i32, i32);
433    string_serialize_via_display!(serialize_i64, i64);
434    string_serialize_via_display!(serialize_u8, u8);
435    string_serialize_via_display!(serialize_u16, u16);
436    string_serialize_via_display!(serialize_u32, u32);
437    string_serialize_via_display!(serialize_u64, u64);
438    string_serialize_via_display!(serialize_f32, f32);
439    string_serialize_via_display!(serialize_f64, f64);
440    string_serialize_via_display!(serialize_char, char);
441    string_serialize_via_display!(serialize_str, &str);
442
443    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
444        Ok(String::from_utf8_lossy(v).to_string())
445    }
446
447    fn serialize_none(self) -> Result<Self::Ok> {
448        self.serialize_unit()
449    }
450
451    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
452    where
453        T: ?Sized + ser::Serialize,
454    {
455        value.serialize(self)
456    }
457
458    fn serialize_unit(self) -> Result<Self::Ok> {
459        Ok(String::new())
460    }
461
462    fn serialize_unit_struct(self, _name: &str) -> Result<Self::Ok> {
463        self.serialize_unit()
464    }
465
466    fn serialize_unit_variant(
467        self,
468        _name: &str,
469        _variant_index: u32,
470        variant: &str,
471    ) -> Result<Self::Ok> {
472        Ok(variant.to_owned())
473    }
474
475    fn serialize_newtype_struct<T>(self, _name: &str, value: &T) -> Result<Self::Ok>
476    where
477        T: ?Sized + ser::Serialize,
478    {
479        value.serialize(self)
480    }
481
482    fn serialize_newtype_variant<T>(
483        self,
484        _name: &str,
485        _variant_index: u32,
486        _variant: &str,
487        value: &T,
488    ) -> Result<Self::Ok>
489    where
490        T: ?Sized + ser::Serialize,
491    {
492        value.serialize(self)
493    }
494
495    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
496        Err(ConfigError::Message(
497            "seq can't serialize to string key".to_owned(),
498        ))
499    }
500
501    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
502        Err(ConfigError::Message(
503            "tuple can't serialize to string key".to_owned(),
504        ))
505    }
506
507    fn serialize_tuple_struct(self, name: &str, _len: usize) -> Result<Self::SerializeTupleStruct> {
508        Err(ConfigError::Message(format!(
509            "tuple struct {name} can't serialize to string key"
510        )))
511    }
512
513    fn serialize_tuple_variant(
514        self,
515        name: &str,
516        _variant_index: u32,
517        variant: &str,
518        _len: usize,
519    ) -> Result<Self::SerializeTupleVariant> {
520        Err(ConfigError::Message(format!(
521            "tuple variant {name}::{variant} can't serialize to string key"
522        )))
523    }
524
525    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
526        Err(ConfigError::Message(
527            "map can't serialize to string key".to_owned(),
528        ))
529    }
530
531    fn serialize_struct(self, name: &str, _len: usize) -> Result<Self::SerializeStruct> {
532        Err(ConfigError::Message(format!(
533            "struct {name} can't serialize to string key"
534        )))
535    }
536
537    fn serialize_struct_variant(
538        self,
539        name: &str,
540        _variant_index: u32,
541        variant: &str,
542        _len: usize,
543    ) -> Result<Self::SerializeStructVariant> {
544        Err(ConfigError::Message(format!(
545            "struct variant {name}::{variant} can't serialize to string key"
546        )))
547    }
548}
549
550impl ser::SerializeSeq for Unreachable {
551    type Ok = String;
552    type Error = ConfigError;
553
554    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
555    where
556        T: ?Sized + ser::Serialize,
557    {
558        match *self {}
559    }
560
561    fn end(self) -> Result<Self::Ok> {
562        match self {}
563    }
564}
565
566impl ser::SerializeTuple for Unreachable {
567    type Ok = String;
568    type Error = ConfigError;
569
570    fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
571    where
572        T: ?Sized + ser::Serialize,
573    {
574        match *self {}
575    }
576
577    fn end(self) -> Result<Self::Ok> {
578        match self {}
579    }
580}
581
582impl ser::SerializeTupleStruct for Unreachable {
583    type Ok = String;
584    type Error = ConfigError;
585
586    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
587    where
588        T: ?Sized + ser::Serialize,
589    {
590        match *self {}
591    }
592
593    fn end(self) -> Result<Self::Ok> {
594        match self {}
595    }
596}
597
598impl ser::SerializeTupleVariant for Unreachable {
599    type Ok = String;
600    type Error = ConfigError;
601
602    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
603    where
604        T: ?Sized + ser::Serialize,
605    {
606        match *self {}
607    }
608
609    fn end(self) -> Result<Self::Ok> {
610        match self {}
611    }
612}
613
614impl ser::SerializeMap for Unreachable {
615    type Ok = String;
616    type Error = ConfigError;
617
618    fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
619    where
620        T: ?Sized + ser::Serialize,
621    {
622        match *self {}
623    }
624
625    fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
626    where
627        T: ?Sized + ser::Serialize,
628    {
629        match *self {}
630    }
631
632    fn end(self) -> Result<Self::Ok> {
633        match self {}
634    }
635}
636
637impl ser::SerializeStruct for Unreachable {
638    type Ok = String;
639    type Error = ConfigError;
640
641    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
642    where
643        T: ?Sized + ser::Serialize,
644    {
645        match *self {}
646    }
647
648    fn end(self) -> Result<Self::Ok> {
649        match self {}
650    }
651}
652
653impl ser::SerializeStructVariant for Unreachable {
654    type Ok = String;
655    type Error = ConfigError;
656
657    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
658    where
659        T: ?Sized + ser::Serialize,
660    {
661        match *self {}
662    }
663
664    fn end(self) -> Result<Self::Ok> {
665        match self {}
666    }
667}
668
669#[cfg(test)]
670mod test {
671    use serde::{Deserialize, Serialize};
672
673    use super::*;
674
675    #[test]
676    fn test_struct() {
677        #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
678        struct Test {
679            int: u32,
680            seq: Vec<String>,
681        }
682
683        let test = Test {
684            int: 1,
685            seq: vec!["a".to_owned(), "b".to_owned()],
686        };
687        let config = Config::try_from(&test).unwrap();
688
689        let actual: Test = config.try_deserialize().unwrap();
690        assert_eq!(test, actual);
691    }
692
693    #[test]
694    #[cfg(feature = "json")]
695    fn test_nest() {
696        let val = serde_json::json! { {
697            "top": {
698                "num": 1,
699                "array": [2],
700                "nested": [[3,4]],
701                "deep": [{
702                    "yes": true,
703                }],
704                "mixed": [
705                    { "boolish": false, },
706                    42,
707                    ["hi"],
708                    { "inner": 66 },
709                    23,
710                ],
711            }
712        } };
713        let config = Config::try_from(&val).unwrap();
714        let output: serde_json::Value = config.try_deserialize().unwrap();
715        assert_eq!(val, output);
716    }
717}