summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaphael Cohn <raphael.cohn@stormmq.com>2017-09-01 09:06:27 +0100
committerRaphael Cohn <raphael.cohn@stormmq.com>2017-09-01 09:06:27 +0100
commit9826b2cda730116e148120dafe0fa89bd389626e (patch)
tree164597d8e40017ca690c259c75eacee9134f6f5d /src
parent13151213a7b368296c616e0a770fb2c238fff1a0 (diff)
Added HJSON (Human-Readable JSON) as a config file format
Diffstat (limited to 'src')
-rw-r--r--src/file/format/hjson.rs55
-rw-r--r--src/file/format/mod.rs13
-rw-r--r--src/lib.rs5
3 files changed, 72 insertions, 1 deletions
diff --git a/src/file/format/hjson.rs b/src/file/format/hjson.rs
new file mode 100644
index 0000000..3d4ad1b
--- /dev/null
+++ b/src/file/format/hjson.rs
@@ -0,0 +1,55 @@
+use serde_hjson;
+use source::Source;
+use std::collections::HashMap;
+use std::error::Error;
+use value::{Value, ValueKind};
+
+pub fn parse(
+ uri: Option<&String>,
+ text: &str,
+) -> Result<HashMap<String, Value>, Box<Error + Send + Sync>> {
+ // Parse a JSON object value from the text
+ // TODO: Have a proper error fire if the root of a file is ever not a Table
+ let value = from_hjson_value(uri, &serde_hjson::from_str(text)?);
+ match value.kind {
+ ValueKind::Table(map) => Ok(map),
+
+ _ => Ok(HashMap::new()),
+ }
+}
+
+fn from_hjson_value(uri: Option<&String>, value: &serde_hjson::Value) -> Value {
+ match *value {
+ serde_hjson::Value::String(ref value) => Value::new(uri, ValueKind::String(value.clone())),
+
+ serde_hjson::Value::I64(value) => Value::new(uri, ValueKind::Integer(value)),
+
+ serde_hjson::Value::U64(value) => Value::new(uri, ValueKind::Integer(value as i64)),
+
+ serde_hjson::Value::F64(value) => Value::new(uri, ValueKind::Float(value)),
+
+ serde_hjson::Value::Bool(value) => Value::new(uri, ValueKind::Boolean(value)),
+
+ serde_hjson::Value::Object(ref table) => {
+ let mut m = HashMap::new();
+
+ for (key, value) in table {
+ m.insert(key.to_lowercase().clone(), from_hjson_value(uri, value));
+ }
+
+ Value::new(uri, ValueKind::Table(m))
+ }
+
+ serde_hjson::Value::Array(ref array) => {
+ let mut l = Vec::new();
+
+ for value in array {
+ l.push(from_hjson_value(uri, value));
+ }
+
+ Value::new(uri, ValueKind::Array(l))
+ }
+
+ serde_hjson::Value::Null => Value::new(uri, ValueKind::Nil),
+ }
+}
diff --git a/src/file/format/mod.rs b/src/file/format/mod.rs
index a90dfda..5dfdfde 100644
--- a/src/file/format/mod.rs
+++ b/src/file/format/mod.rs
@@ -16,6 +16,9 @@ mod json;
#[cfg(feature = "yaml")]
mod yaml;
+#[cfg(feature = "hjson")]
+mod hjson;
+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FileFormat {
/// TOML (parsed with toml)
@@ -29,6 +32,10 @@ pub enum FileFormat {
/// YAML (parsed with yaml_rust)
#[cfg(feature = "yaml")]
Yaml,
+
+ /// HJSON (parsed with serde_hjson)
+ #[cfg(feature = "hjson")]
+ Hjson,
}
lazy_static! {
@@ -46,6 +53,9 @@ lazy_static! {
#[cfg(feature = "yaml")]
formats.insert(FileFormat::Yaml, vec!["yaml", "yml"]);
+ #[cfg(feature = "hjson")]
+ formats.insert(FileFormat::Hjson, vec!["hjson"]);
+
formats
};
}
@@ -77,6 +87,9 @@ impl FileFormat {
#[cfg(feature = "yaml")]
FileFormat::Yaml => yaml::parse(uri, text),
+
+ #[cfg(feature = "hjson")]
+ FileFormat::Hjson => hjson::parse(uri, text),
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index bed60b4..b6eb0f6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,7 +5,7 @@
//! - Environment variables
//! - Another Config instance
//! - Remote configuration: etcd, Consul
-//! - Files: JSON, YAML, TOML
+//! - Files: JSON, YAML, TOML, HJSON
//! - Manual, programmatic override (via a `.set` method on the Config instance)
//!
//! Additionally, Config supports:
@@ -38,6 +38,9 @@ extern crate serde_json;
#[cfg(feature = "yaml")]
extern crate yaml_rust;
+#[cfg(feature = "hjson")]
+extern crate serde_hjson;
+
mod error;
mod value;
mod de;