forked from ScuffleCloud/scuffle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Support for overwrites in ConfigBuilder (resolves ScuffleCloud#103) - Add ManualSource - Fix doc-tests - Fix other minor bugs Co-authored-by: Esdras Amora <[email protected]>
- Loading branch information
1 parent
6325951
commit 2d339f7
Showing
9 changed files
with
220 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
//! Manual source | ||
//! | ||
//! A manual source lets you set values manually. | ||
//! | ||
//! ``` | ||
//! # use config::{sources, Value}; | ||
//! # | ||
//! # #[derive(config::Config, serde::Deserialize)] | ||
//! # struct MyConfig { | ||
//! # // ... | ||
//! # } | ||
//! # | ||
//! # fn main() -> Result<(), config::ConfigError> { | ||
//! let mut builder = config::ConfigBuilder::new(); | ||
//! // Create a new ManualSource | ||
//! let mut manual = sources::ManualSource::new(); | ||
//! manual.set("test.foo", Value::Bool(true)); | ||
//! // Add ManualSource | ||
//! builder.add_source(manual); | ||
//! // Build the final configuration | ||
//! let config: MyConfig = builder.build()?; | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
use std::{collections::BTreeMap, marker::PhantomData}; | ||
|
||
use crate::{ | ||
Config, ConfigError, ConfigErrorType, ErrorSource, KeyPath, KeyPathSegment, Result, Source, | ||
Value, | ||
}; | ||
|
||
use super::utils; | ||
|
||
/// Manual source | ||
/// | ||
/// Create a new manual source with [`ManualSource::new`](ManualSource::new). | ||
pub struct ManualSource<C: Config> { | ||
value: Option<Value>, | ||
_phantom: PhantomData<C>, | ||
} | ||
|
||
fn value_to_value_graph(path: KeyPath, mut value: Value) -> Result<Value> { | ||
for segment in path.into_iter().rev() { | ||
match segment { | ||
KeyPathSegment::Map { key } => { | ||
value = Value::Map(BTreeMap::from([(key, value)])); | ||
} | ||
KeyPathSegment::Seq { index } => { | ||
if index == 0 { | ||
value = Value::Seq(vec![value]); | ||
} else { | ||
return Err(ConfigError::new(ConfigErrorType::ValidationError( | ||
"indices other than 0 not supported when setting values with manual source" | ||
.to_string(), | ||
))); | ||
} | ||
} | ||
} | ||
} | ||
Ok(value) | ||
} | ||
|
||
impl<C: Config> Default for ManualSource<C> { | ||
fn default() -> Self { | ||
Self { | ||
value: None, | ||
_phantom: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl<C: Config> ManualSource<C> { | ||
/// Creates a new manual source. | ||
pub fn new() -> Self { | ||
Self::default() | ||
} | ||
|
||
/// Sets a value at the given path. | ||
pub fn set<K: Into<KeyPath>, V: serde::Serialize>(&mut self, path: K, value: V) -> Result<()> { | ||
let path: KeyPath = path.into(); | ||
let value = serde_value::to_value(value) | ||
.map_err(Into::into) | ||
.map_err(ConfigError::new) | ||
.map_err(|e| e.with_source(ErrorSource::Manual))?; | ||
let value = C::transform(&path, value_to_value_graph(path.clone(), value)?)?; | ||
if let Some(old_value) = self.value.take() { | ||
self.value = Some(crate::merge(value, old_value)); | ||
} else { | ||
self.value = Some(value); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl<C: Config> Source<C> for ManualSource<C> { | ||
fn get_key(&self, path: &crate::KeyPath) -> crate::Result<Option<Value>> { | ||
match &self.value { | ||
Some(value) => { | ||
utils::get_key::<C>(value, path).map_err(|e| e.with_source(ErrorSource::Manual)) | ||
} | ||
None => Ok(None), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.