From 65714bea49036cb2f9188072a8a5d143ac9b9eb9 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Wed, 8 Feb 2017 02:04:56 -0800 Subject: Implement 'namespace' on File --- src/file/json.rs | 16 ++++++++++++++-- src/file/mod.rs | 28 ++++++++++++++-------------- src/file/toml.rs | 16 +++++++++++++--- src/file/yaml.rs | 25 ++++++++++++++++++++----- 4 files changed, 61 insertions(+), 24 deletions(-) (limited to 'src/file') 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> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result, Box> { // 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> { + fn parse(&self, text: &str, namespace: Option<&String>) -> Result, Box> { 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>; + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result, Box>; } pub struct FileSourceString(String); impl FileSource for FileSourceString { - fn try_build(&self, format: FileFormat) -> Result, Box> { - format.parse(&self.0) + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result, Box> { + format.parse(&self.0, namespace) } } @@ -123,7 +123,7 @@ impl FileSourceFile { } impl FileSource for FileSourceFile { - fn try_build(&self, format: FileFormat) -> Result, Box> { + fn try_build(&self, format: FileFormat, namespace: Option<&String>) -> Result, Box> { // 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 File { 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> { - self.source.try_build(self.format) + self.source.try_build(self.format, self.namespace.as_ref()) } } @@ -191,10 +195,6 @@ impl File { 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 SourceBuilder for File { 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> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result, Box> { // 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> { + pub fn parse(text: &str, namespace: Option<&String>) -> Result, Box> { 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 { -- cgit v1.2.3