summaryrefslogtreecommitdiffstats
path: root/src/file
diff options
context:
space:
mode:
authorRyan Leckey <ryan@launchbadge.com>2017-06-22 14:14:29 -0700
committerRyan Leckey <ryan@launchbadge.com>2017-06-22 14:30:51 -0700
commit2b438ed9b53fee5689032f3b5fcdda8d15becd5f (patch)
tree48374e66a6594c7d11d19fe38f7e23df731b52be /src/file
parent04d3ee8f70337e4899932b92262fbeec2dbb1bd9 (diff)
Add builder API to Config
Diffstat (limited to 'src/file')
-rw-r--r--src/file/format/json.rs30
-rw-r--r--src/file/format/mod.rs6
-rw-r--r--src/file/format/toml.rs26
-rw-r--r--src/file/format/yaml.rs34
-rw-r--r--src/file/mod.rs32
-rw-r--r--src/file/source/file.rs17
-rw-r--r--src/file/source/mod.rs7
-rw-r--r--src/file/source/string.rs5
8 files changed, 94 insertions, 63 deletions
diff --git a/src/file/format/json.rs b/src/file/format/json.rs
index 4a94943..290e17d 100644
--- a/src/file/format/json.rs
+++ b/src/file/format/json.rs
@@ -4,25 +4,27 @@ use std::collections::HashMap;
use std::error::Error;
use value::{Value, ValueKind};
-pub fn parse(uri: Option<&String>, text: &str, namespace: Option<&String>) -> Result<HashMap<String, Value>, Box<Error>> {
+pub fn parse(uri: Option<&String>,
+ text: &str,
+ namespace: Option<&String>)
+ -> Result<HashMap<String, Value>, Box<Error>> {
// Parse a JSON object value from the text
let mut root: serde_json::Value = serde_json::from_str(text)?;
// Limit to namespace
if let Some(namespace) = namespace {
root = serde_json::Value::Object(match root {
- serde_json::Value::Object(ref mut table) => {
- if let Some(serde_json::Value::Object(table)) = table.remove(namespace) {
- table
- } else {
- serde_json::Map::new()
- }
- }
+ serde_json::Value::Object(ref mut table) => {
+ if let Some(serde_json::Value::Object(table)) =
+ table.remove(namespace) {
+ table
+ } else {
+ serde_json::Map::new()
+ }
+ }
- _ => {
- serde_json::Map::new()
- }
- });
+ _ => serde_json::Map::new(),
+ });
};
// TODO: Have a proper error fire if the root of a file is ever not a Table
@@ -70,8 +72,6 @@ fn from_json_value(uri: Option<&String>, value: &serde_json::Value) -> Value {
Value::new(uri, ValueKind::Array(l))
}
- serde_json::Value::Null => {
- Value::new(uri, ValueKind::Nil)
- }
+ serde_json::Value::Null => Value::new(uri, ValueKind::Nil),
}
}
diff --git a/src/file/format/mod.rs b/src/file/format/mod.rs
index 287b9b4..3fc15a6 100644
--- a/src/file/format/mod.rs
+++ b/src/file/format/mod.rs
@@ -55,7 +55,11 @@ impl FileFormat {
// TODO: pub(crate)
#[doc(hidden)]
#[allow(unused_variables)]
- pub fn parse(&self, uri: Option<&String>, text: &str, namespace: Option<&String>) -> Result<HashMap<String, Value>, Box<Error>> {
+ pub fn parse(&self,
+ uri: Option<&String>,
+ text: &str,
+ namespace: Option<&String>)
+ -> Result<HashMap<String, Value>, Box<Error>> {
match *self {
#[cfg(feature = "toml")]
FileFormat::Toml => toml::parse(uri, text, namespace),
diff --git a/src/file/format/toml.rs b/src/file/format/toml.rs
index 633f39e..2df1fca 100644
--- a/src/file/format/toml.rs
+++ b/src/file/format/toml.rs
@@ -4,25 +4,27 @@ use std::collections::{HashMap, BTreeMap};
use std::error::Error;
use value::{Value, ValueKind};
-pub fn parse(uri: Option<&String>, text: &str, namespace: Option<&String>) -> Result<HashMap<String, Value>, Box<Error>> {
+pub fn parse(uri: Option<&String>,
+ text: &str,
+ namespace: Option<&String>)
+ -> Result<HashMap<String, Value>, Box<Error>> {
// Parse a TOML value from the provided text
let mut root: toml::Value = toml::from_str(text)?;
// Limit to namespace
if let Some(namespace) = namespace {
root = toml::Value::Table(match root {
- toml::Value::Table(ref mut table) => {
- if let Some(toml::Value::Table(table)) = table.remove(namespace) {
- table
- } else {
- BTreeMap::new()
- }
- }
+ toml::Value::Table(ref mut table) => {
+ if let Some(toml::Value::Table(table)) =
+ table.remove(namespace) {
+ table
+ } else {
+ BTreeMap::new()
+ }
+ }
- _ => {
- BTreeMap::new()
- }
- });
+ _ => BTreeMap::new(),
+ });
}
// TODO: Have a proper error fire if the root of a file is ever not a Table
diff --git a/src/file/format/yaml.rs b/src/file/format/yaml.rs
index 7c3dd71..b1afce7 100644
--- a/src/file/format/yaml.rs
+++ b/src/file/format/yaml.rs
@@ -6,7 +6,10 @@ use std::collections::{BTreeMap, HashMap};
use std::mem;
use value::{Value, ValueKind};
-pub fn parse(uri: Option<&String>, text: &str, namespace: Option<&String>) -> Result<HashMap<String, Value>, Box<Error>> {
+pub fn parse(uri: Option<&String>,
+ text: &str,
+ namespace: Option<&String>)
+ -> Result<HashMap<String, Value>, Box<Error>> {
let mut docs = yaml::YamlLoader::load_from_str(text)?;
// Designate root
@@ -21,18 +24,17 @@ pub fn parse(uri: Option<&String>, text: &str, namespace: Option<&String>) -> Re
// Limit to namespace
if let Some(namespace) = namespace {
root = yaml::Yaml::Hash(match root {
- yaml::Yaml::Hash(ref mut table) => {
- if let Some(yaml::Yaml::Hash(table)) = table.remove(&yaml::Yaml::String(namespace.clone())) {
- table
- } else {
- BTreeMap::new()
- }
- }
+ yaml::Yaml::Hash(ref mut table) => {
+ if let Some(yaml::Yaml::Hash(table)) =
+ table.remove(&yaml::Yaml::String(namespace.clone())) {
+ table
+ } else {
+ BTreeMap::new()
+ }
+ }
- _ => {
- BTreeMap::new()
- }
- });
+ _ => BTreeMap::new(),
+ });
};
// TODO: Have a proper error fire if the root of a file is ever not a Table
@@ -47,7 +49,9 @@ pub fn parse(uri: Option<&String>, text: &str, namespace: Option<&String>) -> Re
fn from_yaml_value(uri: Option<&String>, value: &yaml::Yaml) -> Value {
match *value {
yaml::Yaml::String(ref value) => Value::new(uri, ValueKind::String(value.clone())),
- yaml::Yaml::Real(ref value) => Value::new(uri, ValueKind::Float(value.parse::<f64>().unwrap())),
+ yaml::Yaml::Real(ref value) => {
+ Value::new(uri, ValueKind::Float(value.parse::<f64>().unwrap()))
+ }
yaml::Yaml::Integer(value) => Value::new(uri, ValueKind::Integer(value)),
yaml::Yaml::Boolean(value) => Value::new(uri, ValueKind::Boolean(value)),
yaml::Yaml::Hash(ref table) => {
@@ -70,9 +74,7 @@ fn from_yaml_value(uri: Option<&String>, value: &yaml::Yaml) -> Value {
Value::new(uri, ValueKind::Array(l))
}
- yaml::Yaml::Null => {
- Value::new(uri, ValueKind::Nil)
- }
+ yaml::Yaml::Null => Value::new(uri, ValueKind::Nil),
// TODO: how should we BadValue?
_ => {
diff --git a/src/file/mod.rs b/src/file/mod.rs
index 7fc25c8..671f579 100644
--- a/src/file/mod.rs
+++ b/src/file/mod.rs
@@ -10,6 +10,7 @@ use std::path::Path;
use self::source::FileSource;
pub use self::format::FileFormat;
+#[derive(Clone, Debug)]
pub struct File<T>
where T: FileSource
{
@@ -70,12 +71,19 @@ impl<T: FileSource> File<T> {
}
}
-impl<T: FileSource> Source for File<T> {
+impl<T: FileSource> Source for File<T>
+ where T: 'static,
+ T: Sync + Send
+{
+ fn clone_into_box(&self) -> Box<Source + Send + Sync> {
+ Box::new((*self).clone())
+ }
+
fn collect(&self) -> Result<HashMap<String, Value>> {
// Coerce the file contents to a string
- let (uri, contents, format) = match self.source.resolve(self.format).map_err(|err| {
- ConfigError::Foreign(err)
- }) {
+ let (uri, contents, format) = match self.source
+ .resolve(self.format)
+ .map_err(|err| ConfigError::Foreign(err)) {
Ok((uri, contents, format)) => (uri, contents, format),
Err(error) => {
@@ -88,13 +96,13 @@ impl<T: FileSource> Source for File<T> {
};
// Parse the string using the given format
- let result = format.parse(uri.as_ref(), &contents, self.namespace.as_ref()).map_err(|cause| {
- ConfigError::FileParse {
- uri: uri,
- cause: cause
- }
- });
-
- result
+ format
+ .parse(uri.as_ref(), &contents, self.namespace.as_ref())
+ .map_err(|cause| {
+ ConfigError::FileParse {
+ uri: uri,
+ cause: cause,
+ }
+ })
}
}
diff --git a/src/file/source/file.rs b/src/file/source/file.rs
index 79f46bf..426c0b5 100644
--- a/src/file/source/file.rs
+++ b/src/file/source/file.rs
@@ -3,7 +3,7 @@ use std::result;
use std::error::Error;
use std::path::{PathBuf, Path};
-use ::file::format::ALL_EXTENSIONS;
+use file::format::ALL_EXTENSIONS;
use std::io::{self, Read};
use std::fs;
use std::env;
@@ -13,6 +13,7 @@ use source::Source;
use super::{FileFormat, FileSource};
/// Describes a file sourced from a file
+#[derive(Clone, Debug)]
pub struct FileSourceFile {
/// Basename of configuration file
name: String,
@@ -30,7 +31,9 @@ impl FileSourceFile {
}
}
- fn find_file(&self, format_hint: Option<FileFormat>) -> Result<(PathBuf, FileFormat), Box<Error>> {
+ fn find_file(&self,
+ format_hint: Option<FileFormat>)
+ -> Result<(PathBuf, FileFormat), Box<Error>> {
// Build expected configuration file
let mut basename = PathBuf::new();
@@ -47,7 +50,11 @@ impl FileSourceFile {
Some(format) => Ok((filename, format)),
None => {
for (format, extensions) in ALL_EXTENSIONS.iter() {
- if extensions.contains(&filename.extension().unwrap_or_default().to_string_lossy().as_ref()) {
+ if extensions.contains(&filename
+ .extension()
+ .unwrap_or_default()
+ .to_string_lossy()
+ .as_ref()) {
return Ok((filename, *format));
}
}
@@ -90,7 +97,9 @@ impl FileSourceFile {
}
impl FileSource for FileSourceFile {
- fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>> {
+ fn resolve(&self,
+ format_hint: Option<FileFormat>)
+ -> Result<(Option<String>, String, FileFormat), Box<Error>> {
// Find file
let (filename, format) = self.find_file(format_hint)?;
diff --git a/src/file/source/mod.rs b/src/file/source/mod.rs
index 89f1a3c..67e2cf1 100644
--- a/src/file/source/mod.rs
+++ b/src/file/source/mod.rs
@@ -1,12 +1,15 @@
pub mod file;
pub mod string;
+use std::fmt::Debug;
use std::error::Error;
use source::Source;
use super::FileFormat;
/// Describes where the file is sourced
-pub trait FileSource {
- fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>>;
+pub trait FileSource: Debug + Clone {
+ fn resolve(&self,
+ format_hint: Option<FileFormat>)
+ -> Result<(Option<String>, String, FileFormat), Box<Error>>;
}
diff --git a/src/file/source/string.rs b/src/file/source/string.rs
index 922e46c..70101d6 100644
--- a/src/file/source/string.rs
+++ b/src/file/source/string.rs
@@ -6,6 +6,7 @@ use source::Source;
use super::{FileSource, FileFormat};
/// Describes a file sourced from a string
+#[derive(Clone, Debug)]
pub struct FileSourceString(String);
impl<'a> From<&'a str> for FileSourceString {
@@ -15,7 +16,9 @@ impl<'a> From<&'a str> for FileSourceString {
}
impl FileSource for FileSourceString {
- fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>> {
+ fn resolve(&self,
+ format_hint: Option<FileFormat>)
+ -> Result<(Option<String>, String, FileFormat), Box<Error>> {
Ok((None, self.0.clone(), format_hint.expect("from_str requires a set file format")))
}
}