1use std::collections::HashSet;
2
3use serde::de::{DeserializeSeed, IntoDeserializer, SeqAccess, Visitor};
4use serde::{de, forward_to_deserialize_any};
5
6use crate::error::Error;
7use crate::value::Node;
8
9pub fn from_env<T>() -> Result<T, Error>
32where
33 T: de::DeserializeOwned,
34{
35 T::deserialize(Deserializer(Node::from_env()))
36}
37pub fn from_env_with_prefix<T>(prefix: &str) -> Result<T, Error>
67where
68 T: de::DeserializeOwned,
69{
70 T::deserialize(Deserializer(Node::from_env_with_prefix(prefix)))
71}
72
73pub fn from_iter<Iter, S, T>(iter: Iter) -> Result<T, Error>
102where
103 Iter: IntoIterator<Item = (S, S)>,
104 S: AsRef<str>,
105 T: de::DeserializeOwned,
106{
107 T::deserialize(Deserializer(Node::from_iter(iter)))
108}
109
110pub fn from_iter_with_prefix<Iter, S, T>(iter: Iter, prefix: &str) -> Result<T, Error>
139where
140 Iter: IntoIterator<Item = (S, S)>,
141 S: AsRef<str>,
142 T: de::DeserializeOwned,
143{
144 T::deserialize(Deserializer(Node::from_iter_with_prefix(iter, prefix)))
145}
146
147struct Deserializer(Node);
148
149impl<'de> de::Deserializer<'de> for Deserializer {
150 type Error = Error;
151
152 fn deserialize_any<V>(self, _vis: V) -> Result<V::Value, Self::Error>
153 where
154 V: Visitor<'de>,
155 {
156 Err(de::Error::custom("deserialize_any is not supported"))
157 }
158
159 fn deserialize_bool<V>(self, vis: V) -> Result<V::Value, Self::Error>
160 where
161 V: Visitor<'de>,
162 {
163 vis.visit_bool(self.0.value().parse().map_err(Error::new)?)
164 }
165
166 fn deserialize_i8<V>(self, vis: V) -> Result<V::Value, Self::Error>
167 where
168 V: Visitor<'de>,
169 {
170 vis.visit_i8(self.0.value().parse().map_err(Error::new)?)
171 }
172
173 fn deserialize_i16<V>(self, vis: V) -> Result<V::Value, Self::Error>
174 where
175 V: Visitor<'de>,
176 {
177 vis.visit_i16(self.0.value().parse().map_err(Error::new)?)
178 }
179
180 fn deserialize_i32<V>(self, vis: V) -> Result<V::Value, Self::Error>
181 where
182 V: Visitor<'de>,
183 {
184 vis.visit_i32(self.0.value().parse().map_err(Error::new)?)
185 }
186
187 fn deserialize_i64<V>(self, vis: V) -> Result<V::Value, Self::Error>
188 where
189 V: Visitor<'de>,
190 {
191 vis.visit_i64(self.0.value().parse().map_err(Error::new)?)
192 }
193
194 fn deserialize_u8<V>(self, vis: V) -> Result<V::Value, Self::Error>
195 where
196 V: Visitor<'de>,
197 {
198 vis.visit_u8(self.0.value().parse().map_err(Error::new)?)
199 }
200
201 fn deserialize_u16<V>(self, vis: V) -> Result<V::Value, Self::Error>
202 where
203 V: Visitor<'de>,
204 {
205 vis.visit_u16(self.0.value().parse().map_err(Error::new)?)
206 }
207
208 forward_to_deserialize_any! {
209 unit unit_struct
210 tuple_struct ignored_any
211 }
212
213 fn deserialize_u32<V>(self, vis: V) -> Result<V::Value, Self::Error>
214 where
215 V: Visitor<'de>,
216 {
217 vis.visit_u32(self.0.value().parse().map_err(Error::new)?)
218 }
219
220 fn deserialize_u64<V>(self, vis: V) -> Result<V::Value, Self::Error>
221 where
222 V: Visitor<'de>,
223 {
224 vis.visit_u64(self.0.value().parse().map_err(Error::new)?)
225 }
226
227 fn deserialize_f32<V>(self, vis: V) -> Result<V::Value, Self::Error>
228 where
229 V: Visitor<'de>,
230 {
231 vis.visit_f32(self.0.value().parse().map_err(Error::new)?)
232 }
233
234 fn deserialize_f64<V>(self, vis: V) -> Result<V::Value, Self::Error>
235 where
236 V: Visitor<'de>,
237 {
238 vis.visit_f64(self.0.value().parse().map_err(Error::new)?)
239 }
240
241 fn deserialize_char<V>(self, vis: V) -> Result<V::Value, Self::Error>
242 where
243 V: Visitor<'de>,
244 {
245 vis.visit_char(self.0.value().parse().map_err(Error::new)?)
246 }
247
248 fn deserialize_str<V>(self, vis: V) -> Result<V::Value, Self::Error>
249 where
250 V: Visitor<'de>,
251 {
252 vis.visit_str(self.0.value())
253 }
254
255 fn deserialize_string<V>(self, vis: V) -> Result<V::Value, Self::Error>
256 where
257 V: Visitor<'de>,
258 {
259 vis.visit_string(self.0.into_value())
260 }
261
262 fn deserialize_bytes<V>(self, vis: V) -> Result<V::Value, Self::Error>
263 where
264 V: Visitor<'de>,
265 {
266 vis.visit_bytes(self.0.value().as_bytes())
267 }
268
269 fn deserialize_byte_buf<V>(self, vis: V) -> Result<V::Value, Self::Error>
270 where
271 V: Visitor<'de>,
272 {
273 vis.visit_byte_buf(self.0.into_value().into_bytes())
274 }
275
276 fn deserialize_option<V>(self, vis: V) -> Result<V::Value, Self::Error>
277 where
278 V: Visitor<'de>,
279 {
280 if self.0.is_empty() {
281 vis.visit_none()
282 } else {
283 vis.visit_some(Deserializer(self.0))
284 }
285 }
286
287 fn deserialize_newtype_struct<V>(
288 self,
289 _name: &'static str,
290 vis: V,
291 ) -> Result<V::Value, Self::Error>
292 where
293 V: Visitor<'de>,
294 {
295 vis.visit_newtype_struct(Deserializer(self.0))
296 }
297
298 fn deserialize_seq<V>(self, vis: V) -> Result<V::Value, Self::Error>
299 where
300 V: Visitor<'de>,
301 {
302 let elements = self
303 .0
304 .value()
305 .split(',')
306 .map(|v| v.trim().to_string())
307 .filter(|v| !v.is_empty())
308 .collect();
309
310 vis.visit_seq(SeqAccessor::new(elements))
311 }
312
313 fn deserialize_tuple<V>(self, _len: usize, vis: V) -> Result<V::Value, Self::Error>
314 where
315 V: Visitor<'de>,
316 {
317 let elements = self
318 .0
319 .value()
320 .split(',')
321 .map(|v| v.trim().to_string())
322 .collect();
323
324 vis.visit_seq(SeqAccessor::new(elements))
325 }
326
327 fn deserialize_map<V>(self, vis: V) -> Result<V::Value, Self::Error>
328 where
329 V: Visitor<'de>,
330 {
331 let keys = self.0.flatten("");
332 vis.visit_map(MapAccessor::new(keys, self.0))
333 }
334
335 fn deserialize_struct<V>(
336 self,
337 _name: &'static str,
338 fields: &'static [&'static str],
339 vis: V,
340 ) -> Result<V::Value, Self::Error>
341 where
342 V: Visitor<'de>,
343 {
344 let keys = fields.iter().map(|v| v.to_string()).collect();
345
346 vis.visit_map(MapAccessor::new(keys, self.0))
347 }
348
349 fn deserialize_identifier<V>(self, vis: V) -> Result<V::Value, Self::Error>
350 where
351 V: Visitor<'de>,
352 {
353 self.deserialize_string(vis)
354 }
355
356 fn deserialize_enum<V>(
357 self,
358 _name: &'static str,
359 variants: &'static [&'static str],
360 vis: V,
361 ) -> Result<V::Value, Self::Error>
362 where
363 V: Visitor<'de>,
364 {
365 let keys = variants.iter().map(|v| v.to_string()).collect();
366
367 vis.visit_enum(EnumAccessor::new(keys, self.0))
368 }
369}
370
371struct SeqAccessor {
372 elements: std::vec::IntoIter<String>,
373}
374
375impl SeqAccessor {
376 fn new(keys: Vec<String>) -> Self {
377 Self {
378 elements: keys.into_iter(),
379 }
380 }
381}
382
383impl<'de> SeqAccess<'de> for SeqAccessor {
384 type Error = Error;
385
386 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
387 where
388 T: DeserializeSeed<'de>,
389 {
390 match self.elements.next() {
391 None => Ok(None),
392 Some(v) => Ok(Some(seed.deserialize(Deserializer(Node::new(v)))?)),
393 }
394 }
395}
396
397struct MapAccessor {
398 last_value: Option<Node>,
399 keys: std::collections::hash_set::IntoIter<String>,
400 node: Node,
401}
402
403impl MapAccessor {
404 fn new(keys: HashSet<String>, node: Node) -> Self {
405 Self {
406 last_value: None,
407 keys: keys.into_iter(),
408 node,
409 }
410 }
411}
412
413impl<'de> de::MapAccess<'de> for MapAccessor {
414 type Error = Error;
415
416 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
417 where
418 K: DeserializeSeed<'de>,
419 {
420 debug_assert!(
421 self.last_value.is_none(),
422 "value for the last entry is not deserialized"
423 );
424
425 loop {
426 let key = match self.keys.next() {
427 None => return Ok(None),
428 Some(v) => v,
429 };
430
431 match self.node.get(&key) {
432 None => continue,
434 Some(v) => {
435 self.last_value = Some(v.clone());
436 return Ok(Some(seed.deserialize(key.into_deserializer())?));
437 }
438 }
439 }
440 }
441
442 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
443 where
444 V: DeserializeSeed<'de>,
445 {
446 let value = self
447 .last_value
448 .take()
449 .expect("value for current entry is missing");
450
451 seed.deserialize(Deserializer(value))
452 }
453}
454
455struct EnumAccessor {
456 keys: std::vec::IntoIter<String>,
457 node: Node,
458}
459
460impl EnumAccessor {
461 fn new(keys: Vec<String>, node: Node) -> Self {
462 Self {
463 keys: keys.into_iter(),
464 node,
465 }
466 }
467}
468
469impl<'de> de::EnumAccess<'de> for EnumAccessor {
470 type Error = Error;
471 type Variant = VariantAccessor;
472
473 fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
474 where
475 V: DeserializeSeed<'de>,
476 {
477 let key = self
478 .keys
479 .find(|key| self.node.value() == key)
480 .ok_or_else(|| de::Error::custom("no variant found"))?;
481
482 let variant = VariantAccessor::new(self.node);
483 Ok((seed.deserialize(key.into_deserializer())?, variant))
484 }
485}
486
487struct VariantAccessor {
488 node: Node,
489}
490
491impl VariantAccessor {
492 fn new(node: Node) -> Self {
493 Self { node }
494 }
495}
496
497impl<'de> de::VariantAccess<'de> for VariantAccessor {
498 type Error = Error;
499
500 fn unit_variant(self) -> Result<(), Self::Error> {
501 if self.node.has_children() {
502 return Err(de::Error::custom("variant is not unit"));
503 }
504 Ok(())
505 }
506 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
507 where
508 T: DeserializeSeed<'de>,
509 {
510 seed.deserialize(Deserializer(self.node))
511 }
512 fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
513 where
514 V: Visitor<'de>,
515 {
516 Err(de::Error::custom("tuple variant is not supported"))
517 }
518 fn struct_variant<V>(
519 self,
520 fields: &'static [&'static str],
521 visitor: V,
522 ) -> Result<V::Value, Self::Error>
523 where
524 V: Visitor<'de>,
525 {
526 let keys = fields.iter().map(|v| v.to_string()).collect();
527
528 visitor.visit_map(MapAccessor::new(keys, self.node))
529 }
530}
531
532#[cfg(test)]
533mod tests {
534 use serde::Deserialize;
535 use std::collections::HashMap;
536
537 use super::*;
538
539 #[derive(Deserialize, Default, PartialEq, Debug)]
540 #[serde(default)]
541 struct TestStruct {
542 a: i64,
543 b: bool,
544 c: String,
545 d: EmbedStruct,
546 }
547
548 #[derive(Deserialize, Default, PartialEq, Debug)]
549 #[serde(default)]
550 struct EmbedStruct {
551 aa: f32,
552 bb: String,
553 }
554
555 #[test]
556 fn test_from_env() {
557 temp_env::with_vars(
558 vec![
559 ("A", Some("123")),
560 ("B", Some("true")),
561 ("C", Some("Hello, test")),
562 ("D_AA", Some("1.2")),
563 ("D_BB", Some("Hello, embed")),
564 ],
565 || {
566 let t: TestStruct = from_env().expect("must success");
567 assert_eq!(
568 t,
569 TestStruct {
570 a: 123,
571 b: true,
572 c: "Hello, test".to_string(),
573 d: EmbedStruct {
574 aa: 1.2,
575 bb: "Hello, embed".to_string()
576 }
577 }
578 )
579 },
580 )
581 }
582
583 #[derive(Deserialize, Debug, PartialEq, Eq)]
585 struct Foo {
586 bar: String,
587 baz: bool,
588 zoom: Option<u16>,
589 doom: Vec<u64>,
590 boom: Vec<String>,
591 #[serde(default = "default_kaboom")]
592 kaboom: u16,
593 #[serde(default)]
594 debug_mode: bool,
595 provided: Option<String>,
596 newtype: CustomNewType,
597 boom_zoom: bool,
598 #[serde(default = "default_bool")]
599 mode_xx: bool,
600 }
601
602 fn default_bool() -> bool {
603 true
604 }
605
606 fn default_kaboom() -> u16 {
607 8080
608 }
609
610 #[derive(Deserialize, Debug, PartialEq, Eq, Default)]
611 struct CustomNewType(u32);
612
613 #[test]
614 fn test_ported_from_envy() {
615 temp_env::with_vars(
616 vec![
617 ("BAR", Some("test")),
618 ("BAZ", Some("true")),
619 ("DOOM", Some("1, 2, 3 ")),
620 ("BOOM", Some("")),
622 ("SIZE", Some("small")),
623 ("PROVIDED", Some("test")),
624 ("NEWTYPE", Some("42")),
625 ("boom_zoom", Some("true")),
626 ("mode_xx", Some("false")),
627 ],
628 || {
629 let actual: Foo = from_env().expect("must success");
630 assert_eq!(
631 actual,
632 Foo {
633 bar: String::from("test"),
634 baz: true,
635 zoom: None,
636 doom: vec![1, 2, 3],
637 boom: vec![],
638 kaboom: 8080,
639 debug_mode: false,
640 provided: Some(String::from("test")),
641 newtype: CustomNewType(42),
642 boom_zoom: true,
643 mode_xx: false
644 }
645 )
646 },
647 )
648 }
649
650 #[derive(Deserialize, PartialEq, Debug)]
651 struct TestStructAlias {
652 #[serde(alias = "meta_log_level")]
653 log_level: String,
654 }
655
656 #[test]
658 #[ignore]
659 fn test_from_env_alias() {
660 temp_env::with_vars(vec![("meta_log_level", Some("DEBUG"))], || {
661 let t: TestStructAlias = from_env().expect("must success");
662 assert_eq!(
663 t,
664 TestStructAlias {
665 log_level: "DEBUG".to_string()
666 }
667 )
668 })
669 }
670
671 #[derive(Deserialize, PartialEq, Debug)]
672 struct TestStructFlat {
673 meta_log_level: String,
674 }
675
676 #[test]
677 fn test_from_env_flat() {
678 temp_env::with_vars(vec![("meta_log_level", Some("DEBUG"))], || {
679 let t: TestStructFlat = from_env().expect("must success");
680 assert_eq!(
681 t,
682 TestStructFlat {
683 meta_log_level: "DEBUG".to_string()
684 }
685 )
686 })
687 }
688
689 #[test]
690 fn test_from_env_flat_upper() {
691 temp_env::with_vars(vec![("META_LOG_LEVEL", Some("DEBUG"))], || {
692 let t: TestStructFlat = from_env().expect("must success");
693 assert_eq!(
694 t,
695 TestStructFlat {
696 meta_log_level: "DEBUG".to_string()
697 }
698 )
699 })
700 }
701
702 #[derive(Deserialize, PartialEq, Debug)]
703 struct TestStructFlatWithDefault {
704 meta_log_level: String,
705 }
706
707 impl Default for TestStructFlatWithDefault {
708 fn default() -> Self {
709 Self {
710 meta_log_level: "INFO".to_string(),
711 }
712 }
713 }
714
715 #[test]
716 fn test_from_env_flat_with_default() {
717 temp_env::with_vars(vec![("meta_log_level", Some("DEBUG"))], || {
718 let t: TestStructFlatWithDefault = from_env().expect("must success");
719 assert_eq!(
720 t,
721 TestStructFlatWithDefault {
722 meta_log_level: "DEBUG".to_string()
723 }
724 )
725 })
726 }
727
728 #[test]
729 fn test_from_env_flat_upper_with_default() {
730 temp_env::with_vars(vec![("META_LOG_LEVEL", Some("DEBUG"))], || {
731 let t: TestStructFlatWithDefault = from_env().expect("must success");
732 assert_eq!(
733 t,
734 TestStructFlatWithDefault {
735 meta_log_level: "DEBUG".to_string()
736 }
737 )
738 })
739 }
740
741 #[test]
742 fn test_from_env_as_map() {
743 temp_env::with_vars(vec![("METASRV_LOG_LEVEL", Some("DEBUG"))], || {
744 let t: HashMap<String, String> = from_env().expect("must success");
745 assert_eq!(t["metasrv_log_level"], "DEBUG".to_string())
746 })
747 }
748
749 #[derive(Deserialize, PartialEq, Debug)]
750 struct EnumNewtype {
751 bar: String,
752 }
753
754 #[derive(Deserialize, PartialEq, Debug)]
755 struct ExternallyEnumStruct {
756 foo: ExternallyEnum,
757 }
758
759 #[derive(Deserialize, PartialEq, Debug)]
760 enum ExternallyEnum {
761 X,
762 Y(EnumNewtype),
763 Z { a: i32 },
764 }
765
766 #[test]
767 fn test_from_env_externally_enum() {
768 temp_env::with_vars(vec![("FOO", Some("X"))], || {
769 let t: ExternallyEnumStruct = from_env().expect("must success");
770 assert_eq!(t.foo, ExternallyEnum::X)
771 });
772
773 temp_env::with_vars(vec![("FOO", Some("Y")), ("FOO_BAR", Some("xxx"))], || {
774 let t: ExternallyEnumStruct = from_env().expect("must success");
775 assert_eq!(
776 t.foo,
777 ExternallyEnum::Y(EnumNewtype {
778 bar: "xxx".to_string()
779 })
780 )
781 });
782
783 temp_env::with_vars(vec![("FOO", Some("Z")), ("FOO_A", Some("1"))], || {
784 let t: ExternallyEnumStruct = from_env().expect("must success");
785 assert_eq!(t.foo, ExternallyEnum::Z { a: 1 })
786 });
787 }
788
789 #[derive(Deserialize, PartialEq, Debug)]
790 struct InternallyEnumStruct {
791 foo: InternallyEnum,
792 }
793
794 #[derive(Deserialize, PartialEq, Debug)]
795 #[serde(tag = "type")]
796 enum InternallyEnum {
797 X,
798 Y(EnumNewtype),
799 Z { a: i32 },
800 }
801
802 #[test]
805 #[ignore]
806 fn test_from_env_internally_enum() {
807 temp_env::with_vars(vec![("FOO_TYPE", Some("X"))], || {
808 let t: InternallyEnumStruct = from_env().expect("must success");
809 assert_eq!(t.foo, InternallyEnum::X)
810 });
811
812 temp_env::with_vars(
813 vec![("FOO_TYPE", Some("Y")), ("FOO_BAR", Some("xxx"))],
814 || {
815 let t: InternallyEnumStruct = from_env().expect("must success");
816 assert_eq!(
817 t.foo,
818 InternallyEnum::Y(EnumNewtype {
819 bar: "xxx".to_string()
820 })
821 )
822 },
823 );
824
825 temp_env::with_vars(vec![("FOO_TYPE", Some("Z")), ("FOO_A", Some("1"))], || {
826 let t: InternallyEnumStruct = from_env().expect("must success");
827 assert_eq!(t.foo, InternallyEnum::Z { a: 1 })
828 });
829 }
830
831 #[derive(Deserialize, PartialEq, Debug, Eq)]
832 struct DoubleOptionOuter {
833 inner: Option<DoubleOptionInner>,
834 }
835
836 #[derive(Deserialize, PartialEq, Debug, Eq)]
837 struct DoubleOptionInner {
838 val: Option<u8>,
839 }
840
841 #[test]
842 fn double_option() {
843 temp_env::with_var("INNER_VAL", Some("2"), || {
844 let t: DoubleOptionOuter = from_env().expect("must success");
845 assert_eq!(
846 t,
847 DoubleOptionOuter {
848 inner: Some(DoubleOptionInner { val: Some(2) })
849 }
850 )
851 })
852 }
853}