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