summaryrefslogtreecommitdiffstats
path: root/src/file
diff options
context:
space:
mode:
authorRyan Leckey <leckey.ryan@gmail.com>2017-02-08 02:04:56 -0800
committerRyan Leckey <leckey.ryan@gmail.com>2017-02-08 02:04:56 -0800
commit65714bea49036cb2f9188072a8a5d143ac9b9eb9 (patch)
treef89553c6d06d9de6a314ae02cd37f70c3d3e15b2 /src/file
parent33bc35e1c960b146601083fa1f2d0d602e6152ca (diff)
Implement 'namespace' on File
Diffstat (limited to 'src/file')
-rw-r--r--src/file/json.rs16
-rw-r--r--src/file/mod.rs28
-rw-r--r--src/file/toml.rs16
-rw-r--r--src/file/yaml.rs25
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 {