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;