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
22pub(crate) enum Unreachable {}
24
25pub(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 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 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
410macro_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}