1 use std::iter::IntoIterator;
2 use std::str::FromStr;
3 
4 use crate::error::Result;
5 use crate::map::Map;
6 use crate::source::AsyncSource;
7 use crate::{config::Config, path::Expression, source::Source, value::Value};
8 
9 /// A configuration builder
10 ///
11 /// It registers ordered sources of configuration to later build consistent [`Config`] from them.
12 /// Configuration sources it defines are defaults, [`Source`]s and overrides.
13 ///
14 /// Defaults are always loaded first and can be overwritten by any of two other sources.
15 /// Overrides are always loaded last, thus cannot be overridden.
16 /// Both can be only set explicitly key by key in code
17 /// using [`set_default`](Self::set_default) or [`set_override`](Self::set_override).
18 ///
19 /// An intermediate category, [`Source`], set groups of keys at once implicitly using data coming from external sources
20 /// like files, environment variables or others that one implements. Defining a [`Source`] is as simple as implementing
21 /// a trait for a struct.
22 ///
23 /// Adding sources, setting defaults and overrides does not invoke any I/O nor builds a config.
24 /// It happens on demand when [`build`](Self::build) (or its alternative) is called.
25 /// Therefore all errors, related to any of the [`Source`] will only show up then.
26 ///
27 /// # Sync and async builder
28 ///
29 /// [`ConfigBuilder`] uses type parameter to keep track of builder state.
30 ///
31 /// In [`DefaultState`] builder only supports [`Source`]s
32 ///
33 /// In [`AsyncState`] it supports both [`Source`]s and [`AsyncSource`]s at the price of building using `async fn`.
34 ///
35 /// # Examples
36 ///
37 /// ```rust
38 /// # use config::*;
39 /// # use std::error::Error;
40 /// # fn main() -> Result<(), Box<dyn Error>> {
41 /// let mut builder = Config::builder()
42 ///     .set_default("default", "1")?
43 ///     .add_source(File::new("config/settings", FileFormat::Json))
44 /// //  .add_async_source(...)
45 ///     .set_override("override", "1")?;
46 ///
47 /// match builder.build() {
48 ///     Ok(config) => {
49 ///         // use your config
50 ///     },
51 ///     Err(e) => {
52 ///         // something went wrong
53 ///     }
54 /// }
55 /// # Ok(())
56 /// # }
57 /// ```
58 ///
59 /// If any [`AsyncSource`] is used, the builder will transition to [`AsyncState`].
60 /// In such case, it is required to _await_ calls to [`build`](Self::build) and its non-consuming sibling.
61 ///
62 /// Calls can be not chained as well
63 /// ```rust
64 /// # use std::error::Error;
65 /// # use config::*;
66 /// # fn main() -> Result<(), Box<dyn Error>> {
67 /// let mut builder = Config::builder();
68 /// builder = builder.set_default("default", "1")?;
69 /// builder = builder.add_source(File::new("config/settings", FileFormat::Json));
70 /// builder = builder.add_source(File::new("config/settings.prod", FileFormat::Json));
71 /// builder = builder.set_override("override", "1")?;
72 /// # Ok(())
73 /// # }
74 /// ```
75 ///
76 /// Calling [`Config::builder`](Config::builder) yields builder in the default state.
77 /// If having an asynchronous state as the initial state is desired, _turbofish_ notation needs to be used.
78 /// ```rust
79 /// # use config::{*, builder::AsyncState};
80 /// let mut builder = ConfigBuilder::<AsyncState>::default();
81 /// ```
82 ///
83 /// If for some reason acquiring builder in default state is required without calling [`Config::builder`](Config::builder)
84 /// it can also be achieved.
85 /// ```rust
86 /// # use config::{*, builder::DefaultState};
87 /// let mut builder = ConfigBuilder::<DefaultState>::default();
88 /// ```
89 #[derive(Debug, Clone, Default)]
90 pub struct ConfigBuilder<St: BuilderState> {
91     defaults: Map<Expression, Value>,
92     overrides: Map<Expression, Value>,
93     state: St,
94 }
95 
96 /// Represents [`ConfigBuilder`] state.
97 pub trait BuilderState {}
98 
99 /// Represents data specific to builder in default, sychronous state, without support for async.
100 #[derive(Debug, Default, Clone)]
101 pub struct DefaultState {
102     sources: Vec<Box<dyn Source + Send + Sync>>,
103 }
104 
105 /// The asynchronous configuration builder.
106 ///
107 /// Similar to a [`ConfigBuilder`] it maintains a set of defaults, a set of sources, and overrides.
108 ///
109 /// Defaults do not override anything, sources override defaults, and overrides override anything else.
110 /// Within those three groups order of adding them at call site matters - entities added later take precedence.
111 ///
112 /// For more detailed description and examples see [`ConfigBuilder`].
113 /// [`AsyncConfigBuilder`] is just an extension of it that takes async functions into account.
114 ///
115 /// To obtain a [`Config`] call [`build`](AsyncConfigBuilder::build) or [`build_cloned`](AsyncConfigBuilder::build_cloned)
116 ///
117 /// # Example
118 /// Since this library does not implement any [`AsyncSource`] an example in rustdocs cannot be given.
119 /// Detailed explanation about why such a source is not implemented is in [`AsyncSource`]'s documentation.
120 ///
121 /// Refer to [`ConfigBuilder`] for similar API sample usage or to the examples folder of the crate, where such a source is implemented.
122 #[derive(Debug, Clone, Default)]
123 pub struct AsyncConfigBuilder {}
124 
125 /// Represents data specific to builder in asychronous state, with support for async.
126 #[derive(Debug, Default, Clone)]
127 pub struct AsyncState {
128     sources: Vec<SourceType>,
129 }
130 
131 #[derive(Debug, Clone)]
132 enum SourceType {
133     Sync(Box<dyn Source + Send + Sync>),
134     Async(Box<dyn AsyncSource + Send + Sync>),
135 }
136 
137 impl BuilderState for DefaultState {}
138 impl BuilderState for AsyncState {}
139 
140 impl<St: BuilderState> ConfigBuilder<St> {
141     // operations allowed in any state
142 
143     /// Set a default `value` at `key`
144     ///
145     /// This value can be overwritten by any [`Source`], [`AsyncSource`] or override.
146     ///
147     /// # Errors
148     ///
149     /// Fails if `Expression::from_str(key)` fails.
set_default<S, T>(mut self, key: S, value: T) -> Result<Self> where S: AsRef<str>, T: Into<Value>,150     pub fn set_default<S, T>(mut self, key: S, value: T) -> Result<Self>
151     where
152         S: AsRef<str>,
153         T: Into<Value>,
154     {
155         self.defaults
156             .insert(Expression::from_str(key.as_ref())?, value.into());
157         Ok(self)
158     }
159 
160     /// Set an override
161     ///
162     /// This function sets an overwrite value. It will not be altered by any default, [`Source`] nor [`AsyncSource`]
163     ///
164     /// # Errors
165     ///
166     /// Fails if `Expression::from_str(key)` fails.
set_override<S, T>(mut self, key: S, value: T) -> Result<Self> where S: AsRef<str>, T: Into<Value>,167     pub fn set_override<S, T>(mut self, key: S, value: T) -> Result<Self>
168     where
169         S: AsRef<str>,
170         T: Into<Value>,
171     {
172         self.overrides
173             .insert(Expression::from_str(key.as_ref())?, value.into());
174         Ok(self)
175     }
176 
177     /// Sets an override if value is Some(_)
178     ///
179     /// This function sets an overwrite value if Some(_) is passed. If None is passed, this function does nothing.
180     /// It will not be altered by any default, [`Source`] nor [`AsyncSource`]
181     ///
182     /// # Errors
183     ///
184     /// Fails if `Expression::from_str(key)` fails.
set_override_option<S, T>(mut self, key: S, value: Option<T>) -> Result<Self> where S: AsRef<str>, T: Into<Value>,185     pub fn set_override_option<S, T>(mut self, key: S, value: Option<T>) -> Result<Self>
186     where
187         S: AsRef<str>,
188         T: Into<Value>,
189     {
190         if let Some(value) = value {
191             self.overrides
192                 .insert(Expression::from_str(key.as_ref())?, value.into());
193         }
194         Ok(self)
195     }
196 }
197 
198 impl ConfigBuilder<DefaultState> {
199     // operations allowed in sync state
200 
201     /// Registers new [`Source`] in this builder.
202     ///
203     /// Calling this method does not invoke any I/O. [`Source`] is only saved in internal register for later use.
204     #[must_use]
add_source<T>(mut self, source: T) -> Self where T: Source + Send + Sync + 'static,205     pub fn add_source<T>(mut self, source: T) -> Self
206     where
207         T: Source + Send + Sync + 'static,
208     {
209         self.state.sources.push(Box::new(source));
210         self
211     }
212 
213     /// Registers new [`AsyncSource`] in this builder and forces transition to [`AsyncState`].
214     ///
215     /// Calling this method does not invoke any I/O. [`AsyncSource`] is only saved in internal register for later use.
add_async_source<T>(self, source: T) -> ConfigBuilder<AsyncState> where T: AsyncSource + Send + Sync + 'static,216     pub fn add_async_source<T>(self, source: T) -> ConfigBuilder<AsyncState>
217     where
218         T: AsyncSource + Send + Sync + 'static,
219     {
220         let async_state = ConfigBuilder {
221             state: AsyncState {
222                 sources: self
223                     .state
224                     .sources
225                     .into_iter()
226                     .map(|s| SourceType::Sync(s))
227                     .collect(),
228             },
229             defaults: self.defaults,
230             overrides: self.overrides,
231         };
232 
233         async_state.add_async_source(source)
234     }
235 
236     /// Reads all registered [`Source`]s.
237     ///
238     /// This is the method that invokes all I/O operations.
239     /// For a non consuming alternative see [`build_cloned`](Self::build_cloned)
240     ///
241     /// # Errors
242     /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
243     /// this method returns error.
build(self) -> Result<Config>244     pub fn build(self) -> Result<Config> {
245         Self::build_internal(self.defaults, self.overrides, &self.state.sources)
246     }
247 
248     /// Reads all registered [`Source`]s.
249     ///
250     /// Similar to [`build`](Self::build), but it does not take ownership of `ConfigBuilder` to allow later reuse.
251     /// Internally it clones data to achieve it.
252     ///
253     /// # Errors
254     /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
255     /// this method returns error.
build_cloned(&self) -> Result<Config>256     pub fn build_cloned(&self) -> Result<Config> {
257         Self::build_internal(
258             self.defaults.clone(),
259             self.overrides.clone(),
260             &self.state.sources,
261         )
262     }
263 
build_internal( defaults: Map<Expression, Value>, overrides: Map<Expression, Value>, sources: &[Box<dyn Source + Send + Sync>], ) -> Result<Config>264     fn build_internal(
265         defaults: Map<Expression, Value>,
266         overrides: Map<Expression, Value>,
267         sources: &[Box<dyn Source + Send + Sync>],
268     ) -> Result<Config> {
269         let mut cache: Value = Map::<String, Value>::new().into();
270 
271         // Add defaults
272         for (key, val) in defaults {
273             key.set(&mut cache, val);
274         }
275 
276         // Add sources
277         sources.collect_to(&mut cache)?;
278 
279         // Add overrides
280         for (key, val) in overrides {
281             key.set(&mut cache, val);
282         }
283 
284         Ok(Config::new(cache))
285     }
286 }
287 
288 impl ConfigBuilder<AsyncState> {
289     // operations allowed in async state
290 
291     /// Registers new [`Source`] in this builder.
292     ///
293     /// Calling this method does not invoke any I/O. [`Source`] is only saved in internal register for later use.
294     #[must_use]
add_source<T>(mut self, source: T) -> Self where T: Source + Send + Sync + 'static,295     pub fn add_source<T>(mut self, source: T) -> Self
296     where
297         T: Source + Send + Sync + 'static,
298     {
299         self.state.sources.push(SourceType::Sync(Box::new(source)));
300         self
301     }
302 
303     /// Registers new [`AsyncSource`] in this builder.
304     ///
305     /// Calling this method does not invoke any I/O. [`AsyncSource`] is only saved in internal register for later use.
306     #[must_use]
add_async_source<T>(mut self, source: T) -> Self where T: AsyncSource + Send + Sync + 'static,307     pub fn add_async_source<T>(mut self, source: T) -> Self
308     where
309         T: AsyncSource + Send + Sync + 'static,
310     {
311         self.state.sources.push(SourceType::Async(Box::new(source)));
312         self
313     }
314 
315     /// Reads all registered defaults, [`Source`]s, [`AsyncSource`]s and overrides.
316     ///
317     /// This is the method that invokes all I/O operations.
318     /// For a non consuming alternative see [`build_cloned`](Self::build_cloned)
319     ///
320     /// # Errors
321     /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
322     /// this method returns error.
build(self) -> Result<Config>323     pub async fn build(self) -> Result<Config> {
324         Self::build_internal(self.defaults, self.overrides, &self.state.sources).await
325     }
326 
327     /// Reads all registered defaults, [`Source`]s, [`AsyncSource`]s and overrides.
328     ///
329     /// Similar to [`build`](Self::build), but it does not take ownership of `ConfigBuilder` to allow later reuse.
330     /// Internally it clones data to achieve it.
331     ///
332     /// # Errors
333     /// If source collection fails, be it technical reasons or related to inability to read data as `Config` for different reasons,
334     /// this method returns error.
build_cloned(&self) -> Result<Config>335     pub async fn build_cloned(&self) -> Result<Config> {
336         Self::build_internal(
337             self.defaults.clone(),
338             self.overrides.clone(),
339             &self.state.sources,
340         )
341         .await
342     }
343 
build_internal( defaults: Map<Expression, Value>, overrides: Map<Expression, Value>, sources: &[SourceType], ) -> Result<Config>344     async fn build_internal(
345         defaults: Map<Expression, Value>,
346         overrides: Map<Expression, Value>,
347         sources: &[SourceType],
348     ) -> Result<Config> {
349         let mut cache: Value = Map::<String, Value>::new().into();
350 
351         // Add defaults
352         for (key, val) in defaults {
353             key.set(&mut cache, val);
354         }
355 
356         for source in sources.iter() {
357             match source {
358                 SourceType::Sync(source) => source.collect_to(&mut cache)?,
359                 SourceType::Async(source) => source.collect_to(&mut cache).await?,
360             }
361         }
362 
363         // Add overrides
364         for (key, val) in overrides {
365             key.set(&mut cache, val);
366         }
367 
368         Ok(Config::new(cache))
369     }
370 }
371