1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Conveniently expose (environment) variables to your [`serde`] based data structures,
//! like configurations.
//!
//! The main goal of this library is to allow for a very simple but yet powerful mechanism
//! of dynamically loading single configuration values from (environment) variables.
//! It is ideal, when you need to include sensitive values in configurations, but don't want
//! to or can't (e.g. due to repeated or dynamic values) setup manual environment mappings at compile time.
//!
//! By implementing a [`serde::de::Deserializer`], this crate works independently of the
//! serialization format used and with only a few lines of modifications for any configuration.
//!
//! # Example
//!
//! User provided configuration file:
//!
//! ```json
//! {
//! "redis": {
//! "host": "${REDIS_HOST}",
//! "port": "${REDIS_PORT}"
//! }
//! }
//! ```
//!
//! The configuration file contains the variables, no need to decide on variable mappings at compile time.
//!
//!
//! ```
//! #[derive(Debug, serde::Deserialize)]
//! struct Config {
//! redis: Redis,
//! }
//!
//! #[derive(Debug, serde::Deserialize)]
//! struct Redis {
//! host: std::net::Ipv4Addr,
//! port: u16,
//! }
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let config_path = std::env::args()
//! .nth(1)
//! .unwrap_or_else(|| "config.json".to_owned());
//!
//! # let config_path = file!();
//! let config = std::fs::read_to_string(&config_path)?;
//! # let config = r#"{"redis": {"host": "${REDIS_HOST}", "port": "${REDIS_PORT}"}}"#;
//! # unsafe { std::env::set_var("REDIS_HOST", "127.0.0.1"); }
//! # unsafe { std::env::set_var("REDIS_PORT", "6379"); }
//!
//! let mut source = serde_vars::EnvSource::default();
//!
//! // Before: `let config: Config = serde_json::from_str(&config)?`.
//! // Now:
//! let mut de = serde_json::Deserializer::from_str(&config);
//! let config: Config = serde_vars::deserialize(&mut de, &mut source)?;
//!
//! println!("{config:#?}");
//! # assert_eq!(config.redis.host, std::net::Ipv4Addr::new(127, 0, 0, 1));
//! # assert_eq!(config.redis.port, 6379);
//!
//! Ok(())
//! }
//! ```
//!
//! # String based Lookups
//!
//! `serde-vars` comes packaged with builtin variable sources for environment variables
//! ([`EnvSource`]), hash maps ([`MapSource`]) as well as a generic string based source
//! ([`StringSource`]).
//!
//! In order to guarantee a consistent parsing behaviour, the [`StringSource`] and all of its
//! dependent implementations (like [`EnvSource`]) enforce the following format for all values:
//!
//! - `true` and `false` are always interpreted as a `bool`.
//! - Any positive integer is parsed as a `u64`.
//! - Any negative integer is parsed as a `i64`.
//! - Any floating point value is parsed as a `f64`.
//! - Everything else is parsed as a string. In order to be able to specify numbers as strings,
//! the source recognizes arbitrary values wrapped in `"` as a string. For example `"123"` is
//! parsed as the literal string `123`.
//!
//! For more details read the [`StringSource`] documentation.
//!
//! # File based Lookups
//!
//! Since `0.3` a [`FileSource`] has been added, it functions very similar to a string based
//! source, but has slightly different semantics when it comes to parsing and allows loading
//! arbitrary binary data.
//!
//! # Alternatives
//!
//! Variable expansion is limited to primitive types and not supported for nested data structures,
//! this is currently by design. The intention of this library is not to provide another generic
//! abstraction layer for configurations. If you are looking for a much more powerful mechanism
//! to load and layer [`serde`] based configurations, you should take a look at
//! [`figment`](https://docs.rs/figment/) instead.
pub use Deserializer;
pub use ;
/// Entry point. See [crate documentation](crate) for an example.