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