coalesced/lib.rs
1//! coalesced supports reading configs from multiple sources
2//!
3//! # Usage
4//! ```toml
5//! [dependencies]
6//! coalesced = { git = "https://github.com/hayas1/coalesced" }
7//! ```
8//!
9//! # Examples
10//! [`Coalesce::prior`] will return the last confirmed value. [`Coalesce::posterior`] will return the first confirmed value.
11//! | `Config` | file | env | cli | → | prior | posterior |
12//! | --- | --- | --- | --- | --- | --- | --- |
13//! | `opt_num` | 10 | 100 | | →| 100 | 10 |
14//! | `opt_str` | | hundred | thousand | →| thousand | hundred |
15//! | `boolean` | true | false | true | →| true | true |
16//!
17//! ```rust
18//! use coalesced::Coalesce;
19//!
20//! #[derive(Coalesce)]
21//! pub struct Config<'a> {
22//! opt_num: Option<i32>,
23//! opt_str: Option<&'a str>,
24//! boolean: bool
25//! }
26//!
27//! let from_file = Config {
28//! opt_num: Some(10),
29//! opt_str: None,
30//! boolean: true,
31//! };
32//! let from_env = Config {
33//! opt_num: Some(100),
34//! opt_str: Some("hundred"),
35//! boolean: false,
36//! };
37//! let from_cli = Config {
38//! opt_num: None,
39//! opt_str: Some("thousand"),
40//! boolean: true,
41//! };
42//! let config = from_file.prior(from_env).prior(from_cli);
43//! assert!(matches!(config, Config {
44//! opt_num: Some(100),
45//! opt_str: Some("thousand"),
46//! boolean: true,
47//! }));
48//!
49//! let from_file = Config {
50//! opt_num: Some(10),
51//! opt_str: None,
52//! boolean: true,
53//! };
54//! let from_env = Config {
55//! opt_num: Some(100),
56//! opt_str: Some("hundred"),
57//! boolean: false,
58//! };
59//! let from_cli = Config {
60//! opt_num: None,
61//! opt_str: Some("thousand"),
62//! boolean: true,
63//! };
64//! let config = from_file.posterior(from_env).posterior(from_cli);
65//! assert!(matches!(config, Config {
66//! opt_num: Some(10),
67//! opt_str: Some("hundred"),
68//! boolean: true,
69//! }));
70//! ```
71//!
72//! ### Lazy Evaluation
73//! Related to [`crate::Coalesced`]. Lazy evaluation is supported so we can follow the changes until the value is confirmed.
74//! ```
75//! use coalesced::{Coalesce, History, IntoHistory};
76//!
77//! #[derive(Coalesce)]
78//! pub struct Config<'a> {
79//! opt_num: Option<i32>,
80//! opt_str: Option<&'a str>,
81//! boolean: bool,
82//! }
83//!
84//! let from_file = Config {
85//! opt_num: Some(10),
86//! opt_str: None,
87//! boolean: true,
88//! };
89//! let from_env = Config {
90//! opt_num: Some(100),
91//! opt_str: Some("hundred"),
92//! boolean: false,
93//! };
94//! let from_cli = Config {
95//! opt_num: None,
96//! opt_str: Some("thousand"),
97//! boolean: true,
98//! };
99//!
100//! let config = from_file.into_history().prior(from_env).prior(from_cli);
101//! assert!(matches!(
102//! config.base(),
103//! Config {
104//! opt_num: Some(10),
105//! opt_str: None,
106//! boolean: true,
107//! }
108//! ));
109//! assert!(matches!(config.into(), Config {
110//! opt_num: Some(100),
111//! opt_str: Some("thousand"),
112//! boolean: true,
113//! }));
114//! ```
115//!
116//! ### Extensions metadata
117//! Related to [`crate::WithExt`]. Extensions metadata is supported so we can follow the source of the confirmed value.
118//! ```
119//! use coalesced::{Coalesce, Extension};
120//!
121//! #[derive(Coalesce)]
122//! pub struct Config<'a> {
123//! opt_num: Option<i32>,
124//! opt_str: Option<&'a str>,
125//! boolean: bool,
126//! }
127//!
128//! let from_file = Config {
129//! opt_num: Some(10),
130//! opt_str: None,
131//! boolean: true,
132//! };
133//! let from_env = Config {
134//! opt_num: Some(100),
135//! opt_str: Some("hundred"),
136//! boolean: false,
137//! };
138//! let from_cli = Config {
139//! opt_num: None,
140//! opt_str: Some("thousand"),
141//! boolean: true,
142//! };
143//!
144//! let (file, env, cli) = (
145//! from_file.with_extension(&"file"),
146//! from_env.with_extension(&"env"),
147//! from_cli.with_extension(&"cli"),
148//! );
149//!
150//! let config = file.prior(env).prior(cli);
151//! assert_eq!(config.opt_num.extension, &"env");
152//! assert_eq!(config.opt_str.extension, &"cli");
153//! assert_eq!(config.boolean.extension, &"cli");
154//! assert!(matches!(config.into(), Config {
155//! opt_num: Some(100),
156//! opt_str: Some("thousand"),
157//! boolean: true
158//! }));
159//! ```
160//!
161//! # Documents
162//! <https://hayas1.github.io/coalesced/coalesced>
163//!
164//! # Testing
165//! ## Benchmarks
166//! TODO
167//!
168//! ## Coverage
169//! <https://hayas1.github.io/coalesced/coalesced/tarpaulin-report.html>
170//!
171
172pub use coalesced_base::{
173 coalesce::Coalesce,
174 coalesced::{Coalesced, History, IntoHistory},
175 extension::{Extension, WithExt},
176};
177
178#[cfg(feature = "derive")]
179pub use coalesced_derive::Coalesce;