diff options
author | Ryan Leckey <leckey.ryan@gmail.com> | 2017-02-08 02:04:56 -0800 |
---|---|---|
committer | Ryan Leckey <leckey.ryan@gmail.com> | 2017-02-08 02:04:56 -0800 |
commit | 65714bea49036cb2f9188072a8a5d143ac9b9eb9 (patch) | |
tree | f89553c6d06d9de6a314ae02cd37f70c3d3e15b2 /src/file | |
parent | 33bc35e1c960b146601083fa1f2d0d602e6152ca (diff) |
Implement 'namespace' on File
Diffstat (limited to 'src/file')
-rw-r--r-- | src/file/json.rs | 16 | ||||
-rw-r--r-- | src/file/mod.rs | 28 | ||||
-rw-r--r-- | src/file/toml.rs | 16 | ||||
-rw-r--r-- | src/file/yaml.rs | 25 |
4 files changed, 61 insertions, 24 deletions
diff --git a/src/file/json.rs b/src/file/json.rs index 86612c9..64c6236 100644 --- a/src/file/json.rs +++ b/src/file/json.rs @@ -11,9 +11,21 @@ pub struct Content { } impl Content { - pub fn parse(text: &str) -> Result<Box<Source>, Box<Error>> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { // Parse - let root = serde_json::from_str(text)?; + let mut root: serde_json::Value = serde_json::from_str(text)?; + + // Limit to namespace + if let Some(namespace) = namespace { + if let serde_json::Value::Object(mut root_map) = root { + if let Some(value) = root_map.remove(namespace) { + root = value; + } else { + // TODO: Warn? + root = serde_json::Value::Object(serde_json::Map::new()); + } + } + } Ok(Box::new(Content { root: root })) } diff --git a/src/file/mod.rs b/src/file/mod.rs index 8f9578d..519a4bf 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -47,29 +47,29 @@ impl FileFormat { } #[allow(unused_variables)] - fn parse(&self, text: &str) -> Result<Box<Source>, Box<Error>> { + fn parse(&self, text: &str, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { match *self { #[cfg(feature = "toml")] - FileFormat::Toml => toml::Content::parse(text), + FileFormat::Toml => toml::Content::parse(text, namespace), #[cfg(feature = "json")] - FileFormat::Json => json::Content::parse(text), + FileFormat::Json => json::Content::parse(text, namespace), #[cfg(feature = "yaml")] - FileFormat::Yaml => yaml::Content::parse(text), + FileFormat::Yaml => yaml::Content::parse(text, namespace), } } } pub trait FileSource { - fn try_build(&self, format: FileFormat) -> Result<Box<Source>, Box<Error>>; + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>>; } pub struct FileSourceString(String); impl FileSource for FileSourceString { - fn try_build(&self, format: FileFormat) -> Result<Box<Source>, Box<Error>> { - format.parse(&self.0) + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { + format.parse(&self.0, namespace) } } @@ -123,7 +123,7 @@ impl FileSourceFile { } impl FileSource for FileSourceFile { - fn try_build(&self, format: FileFormat) -> Result<Box<Source>, Box<Error>> { + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { // Find file let filename = self.find_file(format)?; @@ -133,7 +133,7 @@ impl FileSource for FileSourceFile { file.read_to_string(&mut text)?; // Parse the file - format.parse(&text) + format.parse(&text, namespace) } } @@ -181,9 +181,13 @@ impl<T: FileSource> File<T> { File { required: required, ..self } } + pub fn namespace(self, namespace: &str) -> Self { + File { namespace: Some(namespace.into()), ..self } + } + // Build normally and return error on failure fn try_build(&self) -> Result<Box<Source>, Box<Error>> { - self.source.try_build(self.format) + self.source.try_build(self.format, self.namespace.as_ref()) } } @@ -191,10 +195,6 @@ impl File<FileSourceFile> { pub fn path(self, path: &str) -> Self { File { source: FileSourceFile { path: Some(path.into()), ..self.source }, ..self } } - - pub fn namespace(self, namespace: &str) -> Self { - File { namespace: Some(namespace.into()), ..self } - } } impl<T: FileSource> SourceBuilder for File<T> { diff --git a/src/file/toml.rs b/src/file/toml.rs index 28a1507..e3fb0d8 100644 --- a/src/file/toml.rs +++ b/src/file/toml.rs @@ -1,6 +1,6 @@ use toml; use source::Source; -use std::collections::HashMap; +use std::collections::{HashMap, BTreeMap}; use std::error::Error; use value::Value; @@ -10,11 +10,21 @@ pub struct Content { } impl Content { - pub fn parse(text: &str) -> Result<Box<Source>, Box<Error>> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { // Parse let mut parser = toml::Parser::new(text); // TODO: Get a solution to make this return an Error-able - let root = parser.parse().unwrap(); + let mut root = parser.parse().unwrap(); + + // Limit to namespace + if let Some(namespace) = namespace { + if let Some(toml::Value::Table(table)) = root.remove(namespace) { + root = table; + } else { + // TODO: Warn? + root = BTreeMap::new(); + } + } Ok(Box::new(Content { root: toml::Value::Table(root) })) } diff --git a/src/file/yaml.rs b/src/file/yaml.rs index 72a987a..00b749c 100644 --- a/src/file/yaml.rs +++ b/src/file/yaml.rs @@ -13,14 +13,29 @@ pub struct Content { } impl Content { - pub fn parse(text: &str) -> Result<Box<Source>, Box<Error>> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result<Box<Source>, Box<Error>> { let mut docs = yaml::YamlLoader::load_from_str(text)?; - match docs.len() { - 0 => Ok(Box::new(Content { root: yaml::Yaml::Hash(BTreeMap::new()) })), - 1 => Ok(Box::new(Content { root: mem::replace(&mut docs[0], yaml::Yaml::Null) })), - n => Err(Box::new(MultipleDocumentsError(n))), + // Designate root + let mut root = match docs.len() { + 0 => yaml::Yaml::Hash(BTreeMap::new()), + 1 => mem::replace(&mut docs[0], yaml::Yaml::Null), + n => { return Err(Box::new(MultipleDocumentsError(n))); } + }; + + // Limit to namespace + if let Some(namespace) = namespace { + if let yaml::Yaml::Hash(mut root_map) = root { + if let Some(value) = root_map.remove(&yaml::Yaml::String(namespace.clone())) { + root = value; + } else { + // TODO: Warn? + root = yaml::Yaml::Hash(BTreeMap::new()); + } + } } + + Ok(Box::new(Content { root: root })) } pub fn from_yaml(doc: yaml::Yaml) -> Content { |