diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2022-06-21 11:04:46 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2022-06-21 11:08:45 +0200 |
commit | 7a9bed3fa0dd7680fe7bb4141f9945f4b590bfca (patch) | |
tree | f7fe7198cd2c92bd51249a3b0e3ce55908deb2cc | |
parent | 50d7f714fc57167e88168b0212390295f73b2b21 (diff) |
Add StringSource
This patch adds a type for a String buffer as a source for the
configuration as well as format parser interfaces.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | src/element/mod.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/source/format.rs | 23 | ||||
-rw-r--r-- | src/source/mod.rs (renamed from src/source.rs) | 21 | ||||
-rw-r--r-- | src/source/string.rs | 49 |
5 files changed, 95 insertions, 1 deletions
diff --git a/src/element/mod.rs b/src/element/mod.rs index 3425bed..6059651 100644 --- a/src/element/mod.rs +++ b/src/element/mod.rs @@ -27,7 +27,7 @@ pub trait AsConfigElement { } #[cfg(feature = "json")] -mod json; +pub mod json; #[cfg(feature = "toml")] mod toml; @@ -7,3 +7,4 @@ mod source; pub use crate::config::Config; pub use crate::source::ConfigSource; +pub use crate::source::StringSource; diff --git a/src/source/format.rs b/src/source/format.rs new file mode 100644 index 0000000..b2e6551 --- /dev/null +++ b/src/source/format.rs @@ -0,0 +1,23 @@ +use crate::element::AsConfigElement; + +use super::SourceError; + +pub trait FormatParser: std::fmt::Debug { + type Output: AsConfigElement + std::fmt::Debug + Sized; + + fn parse(buffer: &str) -> Result<Self::Output, SourceError>; +} + +#[cfg(feature = "json")] +#[derive(Debug)] +pub struct JsonFormatParser; + +#[cfg(feature = "json")] +impl FormatParser for JsonFormatParser { + type Output = serde_json::Value; + + fn parse(buffer: &str) -> Result<Self::Output, SourceError> { + serde_json::from_str(buffer).map_err(SourceError::JsonParserError) + } +} + diff --git a/src/source.rs b/src/source/mod.rs index 485da8a..3b2dd87 100644 --- a/src/source.rs +++ b/src/source/mod.rs @@ -1,11 +1,31 @@ use crate::object::ConfigObject; +mod format; +mod string; + +pub use crate::source::string::StringSource; +pub use crate::source::format::FormatParser; +pub use crate::source::format::JsonFormatParser; + pub trait ConfigSource: std::fmt::Debug { type Error: std::error::Error; fn load<'a>(&'a self) -> Result<ConfigObject<'a>, Self::Error>; } +#[derive(Debug, thiserror::Error)] +pub enum SourceError { + #[error("IO Error")] + Io(#[from] std::io::Error), + + #[cfg(feature = "json")] + #[error("JSON Parser error")] + JsonParserError(#[from] serde_json::Error), + + #[cfg(feature = "json")] + #[error("JSON load error")] + JsonLoadError(#[from] crate::element::json::JsonIntoConfigElementError), +} #[cfg(test)] pub(crate) mod test_source { @@ -35,3 +55,4 @@ pub(crate) mod test_source { } } } + diff --git a/src/source/string.rs b/src/source/string.rs new file mode 100644 index 0000000..e09e7f2 --- /dev/null +++ b/src/source/string.rs @@ -0,0 +1,49 @@ +use crate::ConfigSource; +use crate::description::ConfigSourceDescription; +use crate::element::AsConfigElement; +use crate::object::ConfigObject; +use crate::source::format::FormatParser; + +use super::SourceError; + +#[derive(Debug)] +pub struct StringSource<P: FormatParser + std::fmt::Debug> { + data: P::Output, +} + +impl<P: FormatParser> StringSource<P> { + pub fn new(buffer: &str) -> Result<Self, SourceError> { + Ok(StringSource { + data: P::parse(buffer)?, + }) + } +} + +impl<P: FormatParser + std::fmt::Debug> ConfigSource for StringSource<P> + where SourceError: From<<<P as FormatParser>::Output as AsConfigElement>::Error> +{ + type Error = SourceError; + + fn load<'a>(&'a self) -> Result<ConfigObject<'a>, Self::Error> { + let element = self.data + .as_config_element()?; + + let desc = ConfigSourceDescription::Custom("String".to_string()); + Ok(ConfigObject::new(element, desc)) + } +} + +#[cfg(test)] +mod test_source_impl { + #[cfg(feature = "json")] + #[test] + fn test_json_string_source() { + use super::*; + + let source = "{}"; + + let source = StringSource::<crate::source::JsonFormatParser>::new(source).unwrap(); + let _object = source.load().unwrap(); + } +} + |