summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Orchard <if_coding@fastmail.com>2021-08-01 00:03:10 -0700
committerDavid Orchard <if_coding@fastmail.com>2021-08-15 10:31:58 -0700
commitcc0530a7716779f954b1756905a9f4ceb7eb6d62 (patch)
tree311b2ca44a282bbc629a08123f53a855cba38c1c
parent622efaca17256fb42dafc61c8df1f3037c1fb772 (diff)
Move order preservation under a feature gate
-rw-r--r--Cargo.toml12
-rw-r--r--examples/async_source/main.rs5
-rw-r--r--examples/glob/src/main.rs14
-rw-r--r--examples/simple/src/main.rs6
-rw-r--r--examples/watch/src/main.rs4
-rw-r--r--src/builder.rs23
-rw-r--r--src/config.rs12
-rw-r--r--src/de.rs4
-rw-r--r--src/env.rs6
-rw-r--r--src/file/format/hjson.rs8
-rw-r--r--src/file/format/ini.rs8
-rw-r--r--src/file/format/json.rs8
-rw-r--r--src/file/format/json5.rs8
-rw-r--r--src/file/format/mod.rs8
-rw-r--r--src/file/format/ron.rs8
-rw-r--r--src/file/format/toml.rs8
-rw-r--r--src/file/format/yaml.rs8
-rw-r--r--src/file/mod.rs6
-rw-r--r--src/lib.rs2
-rw-r--r--src/map.rs4
-rw-r--r--src/path/mod.rs10
-rw-r--r--src/source.rs22
-rw-r--r--src/value.rs10
-rw-r--r--tests/async_builder.rs5
-rw-r--r--tests/errors.rs5
-rw-r--r--tests/file_hjson.rs3
-rw-r--r--tests/file_json.rs32
-rw-r--r--tests/file_json5.rs32
-rw-r--r--tests/file_ron.rs32
-rw-r--r--tests/file_toml.rs32
-rw-r--r--tests/file_yaml.rs32
-rw-r--r--tests/get.rs36
-rw-r--r--tests/legacy/errors.rs3
-rw-r--r--tests/legacy/file_hjson.rs3
-rw-r--r--tests/legacy/file_json.rs32
-rw-r--r--tests/legacy/file_ron.rs32
-rw-r--r--tests/legacy/file_toml.rs32
-rw-r--r--tests/legacy/file_yaml.rs32
-rw-r--r--tests/legacy/get.rs36
-rw-r--r--tests/legacy/merge.rs26
-rw-r--r--tests/merge.rs26
41 files changed, 358 insertions, 277 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3c2e622..8d76ba0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,7 @@ yaml = ["yaml-rust"]
hjson = ["serde-hjson"]
ini = ["rust-ini"]
json5 = ["json5_rs"]
+preserve_order = ["linked-hash-map", "toml/preserve_order", "serde_json/preserve_order", "ron/indexmap"]
[dependencies]
async-trait = "0.1.50"
@@ -28,14 +29,14 @@ lazy_static = "1.0"
serde = "1.0.8"
nom = "6"
-toml = { version = "0.5", features = ["preserve_order"], optional = true }
-serde_json = { version = "1.0.2", features = ["std", "preserve_order"], optional = true }
+toml = { version = "0.5", optional = true }
+serde_json = { version = "1.0.2", optional = true }
yaml-rust = { version = "0.4", optional = true }
serde-hjson = { version = "0.9", default-features = false, optional = true }
rust-ini = { version = "0.17", optional = true }
-ron = { version = "0.6", features = ["indexmap"], optional = true }
+ron = { version = "0.6", optional = true }
json5_rs = { version = "0.3", optional = true, package = "json5" }
-linked-hash-map = { version = "0.5.4", features = ["serde_impl"] }
+linked-hash-map = { version = "0.5.4", optional = true, features = ["serde_impl"] }
[dev-dependencies]
serde_derive = "1.0.8"
@@ -45,3 +46,6 @@ tokio = { version = "1", features = ["rt-multi-thread", "macros", "fs", "io-util
warp = "0.3.1"
futures = "0.3.15"
reqwest = "0.11.3"
+# Workaround to activate non-default features for tests:
+# https://github.com/rust-lang/cargo/issues/2911
+config = { path = ".", features = ["preserve_order"] }
diff --git a/examples/async_source/main.rs b/examples/async_source/main.rs
index 6c836a3..5134822 100644
--- a/examples/async_source/main.rs
+++ b/examples/async_source/main.rs
@@ -1,7 +1,6 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
-use config::{builder::AsyncState, AsyncSource, ConfigBuilder, ConfigError, FileFormat};
+use config::{builder::AsyncState, AsyncSource, ConfigBuilder, ConfigError, FileFormat, MapImpl};
use async_trait::async_trait;
use futures::{select, FutureExt};
@@ -57,7 +56,7 @@ struct HttpSource {
#[async_trait]
impl AsyncSource for HttpSource {
- async fn collect(&self) -> Result<LinkedHashMap<String, config::Value>, ConfigError> {
+ async fn collect(&self) -> Result<MapImpl<String, config::Value>, ConfigError> {
reqwest::get(&self.uri)
.await
.map_err(|e| ConfigError::Foreign(Box::new(e)))? // error conversion is possible from custom AsyncSource impls
diff --git a/examples/glob/src/main.rs b/examples/glob/src/main.rs
index c85f86e..d429917 100644
--- a/examples/glob/src/main.rs
+++ b/examples/glob/src/main.rs
@@ -1,5 +1,5 @@
use std::path::Path;
-use std::collections::LinkedHashMap;
+use std::collections::MapImpl;
use config::*;
use glob::glob;
@@ -14,9 +14,9 @@ fn main() {
.merge(File::from(Path::new("conf/05-some.yml"))).unwrap()
.merge(File::from(Path::new("conf/99-extra.json"))).unwrap();
- // Print out our settings (as a LinkedHashMap)
+ // Print out our settings (as a MapImpl)
println!("\n{:?} \n\n-----------",
- settings.try_into::<LinkedHashMap<String, String>>().unwrap());
+ settings.try_into::<MapImpl<String, String>>().unwrap());
// Option 2
// --------
@@ -28,9 +28,9 @@ fn main() {
File::from(Path::new("conf/99-extra.json"))])
.unwrap();
- // Print out our settings (as a LinkedHashMap)
+ // Print out our settings (as a MapImpl)
println!("\n{:?} \n\n-----------",
- settings.try_into::<LinkedHashMap<String, String>>().unwrap());
+ settings.try_into::<MapImpl<String, String>>().unwrap());
// Option 3
// --------
@@ -43,7 +43,7 @@ fn main() {
.collect::<Vec<_>>())
.unwrap();
- // Print out our settings (as a LinkedHashMap)
+ // Print out our settings (as a MapImpl)
println!("\n{:?} \n\n-----------",
- settings.try_into::<LinkedHashMap<String, String>>().unwrap());
+ settings.try_into::<MapImpl<String, String>>().unwrap());
}
diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs
index 698401a..5d4c3bc 100644
--- a/examples/simple/src/main.rs
+++ b/examples/simple/src/main.rs
@@ -1,4 +1,4 @@
-use std::collections::LinkedHashMap;
+use std::collections::MapImpl;
fn main() {
let mut settings = config::Config::default();
@@ -9,7 +9,7 @@ fn main() {
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
.merge(config::Environment::with_prefix("APP")).unwrap();
- // Print out our settings (as a LinkedHashMap)
+ // Print out our settings (as a MapImpl)
println!("{:?}",
- settings.try_into::<LinkedHashMap<String, String>>().unwrap());
+ settings.try_into::<MapImpl<String, String>>().unwrap());
}
diff --git a/examples/watch/src/main.rs b/examples/watch/src/main.rs
index 9e676ad..fed4ed0 100644
--- a/examples/watch/src/main.rs
+++ b/examples/watch/src/main.rs
@@ -1,5 +1,5 @@
use config::*;
-use std::collections::LinkedHashMap;
+use std::collections::MapImpl;
use std::sync::RwLock;
use notify::{RecommendedWatcher, DebouncedEvent, Watcher, RecursiveMode};
use std::sync::mpsc::channel;
@@ -20,7 +20,7 @@ fn show() {
.read()
.unwrap()
.clone()
- .try_into::<LinkedHashMap<String, String>>()
+ .try_into::<MapImpl<String, String>>()
.unwrap());
}
diff --git a/src/builder.rs b/src/builder.rs
index 65f49ae..5100f5f 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1,8 +1,9 @@
-use linked_hash_map::LinkedHashMap;
use std::iter::IntoIterator;
use std::str::FromStr;
+
use crate::error::Result;
+use crate::map::MapImpl;
use crate::source::AsyncSource;
use crate::{config::Config, path::Expression, source::Source, value::Value};
@@ -88,8 +89,8 @@ use crate::{config::Config, path::Expression, source::Source, value::Value};
/// ```
#[derive(Debug, Clone, Default)]
pub struct ConfigBuilder<St: BuilderState> {
- defaults: LinkedHashMap<Expression, Value>,
- overrides: LinkedHashMap<Expression, Value>,
+ defaults: MapImpl<Expression, Value>,
+ overrides: MapImpl<Expression, Value>,
state: St,
}
@@ -121,8 +122,8 @@ pub struct DefaultState {
/// Refer to [`ConfigBuilder`] for similar API sample usage or to the examples folder of the crate, where such a source is implemented.
#[derive(Debug, Clone, Default)]
pub struct AsyncConfigBuilder {
- defaults: LinkedHashMap<Expression, Value>,
- overrides: LinkedHashMap<Expression, Value>,
+ defaults: MapImpl<Expression, Value>,
+ overrides: MapImpl<Expression, Value>,
sources: Vec<SourceType>,
}
@@ -245,11 +246,11 @@ impl ConfigBuilder<DefaultState> {
}
fn build_internal(
- defaults: LinkedHashMap<Expression, Value>,
- overrides: LinkedHashMap<Expression, Value>,
+ defaults: MapImpl<Expression, Value>,
+ overrides: MapImpl<Expression, Value>,
sources: &[Box<dyn Source + Send + Sync>],
) -> Result<Config> {
- let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
+ let mut cache: Value = MapImpl::<String, Value>::new().into();
// Add defaults
for (key, val) in defaults.into_iter() {
@@ -323,11 +324,11 @@ impl ConfigBuilder<AsyncState> {
}
async fn build_internal(
- defaults: LinkedHashMap<Expression, Value>,
- overrides: LinkedHashMap<Expression, Value>,
+ defaults: MapImpl<Expression, Value>,
+ overrides: MapImpl<Expression, Value>,
sources: &[SourceType],
) -> Result<Config> {
- let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
+ let mut cache: Value = MapImpl::<String, Value>::new().into();
// Add defaults
for (key, val) in defaults.into_iter() {
diff --git a/src/config.rs b/src/config.rs
index 6302c45..8c410f0 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,3 @@
-use linked_hash_map::LinkedHashMap;
use std::fmt::Debug;
use crate::builder::{ConfigBuilder, DefaultState};
@@ -6,6 +5,7 @@ use serde::de::Deserialize;
use serde::ser::Serialize;
use crate::error::*;
+use crate::map::MapImpl;
use crate::path;
use crate::ser::ConfigSerializer;
use crate::source::Source;
@@ -16,8 +16,8 @@ use crate::value::{Table, Value};
/// them according to the source's priority.
#[derive(Clone, Debug)]
pub struct Config {
- defaults: LinkedHashMap<path::Expression, Value>,
- overrides: LinkedHashMap<path::Expression, Value>,
+ defaults: MapImpl<path::Expression, Value>,
+ overrides: MapImpl<path::Expression, Value>,
sources: Vec<Box<dyn Source + Send + Sync>>,
/// Root of the cached configuration.
@@ -83,7 +83,7 @@ impl Config {
#[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn refresh(&mut self) -> Result<&mut Config> {
self.cache = {
- let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
+ let mut cache: Value = MapImpl::<String, Value>::new().into();
// Add defaults
for (key, val) in self.defaults.iter() {
@@ -181,7 +181,7 @@ impl Config {
self.get(key).and_then(Value::into_bool)
}
- pub fn get_table(&self, key: &str) -> Result<LinkedHashMap<String, Value>> {
+ pub fn get_table(&self, key: &str) -> Result<MapImpl<String, Value>> {
self.get(key).and_then(Value::into_table)
}
@@ -212,7 +212,7 @@ impl Source for Config {
Box::new((*self).clone())
}
- fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ fn collect(&self) -> Result<MapImpl<String, Value>> {
self.cache.clone().into_table()
}
}
diff --git a/src/de.rs b/src/de.rs
index 7d66896..9aa6b45 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -1,4 +1,3 @@
-use linked_hash_map::LinkedHashMap;
use std::collections::VecDeque;
use std::iter::Enumerate;
@@ -6,6 +5,7 @@ use serde::de;
use crate::config::Config;
use crate::error::*;
+use crate::map::MapImpl;
use crate::value::{Table, Value, ValueKind};
impl<'de> de::Deserializer<'de> for Value {
@@ -200,7 +200,7 @@ struct MapAccess {
}
impl MapAccess {
- fn new(table: LinkedHashMap<String, Value>) -> Self {
+ fn new(table: MapImpl<String, Value>) -> Self {
MapAccess {
elements: table.into_iter().collect(),
}
diff --git a/src/env.rs b/src/env.rs
index 2e48701..507ace6 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -1,7 +1,7 @@
-use linked_hash_map::LinkedHashMap;
use std::env;
use crate::error::*;
+use crate::map::MapImpl;
use crate::source::Source;
use crate::value::{Value, ValueKind};
@@ -79,8 +79,8 @@ impl Source for Environment {
Box::new((*self).clone())
}
- fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
- let mut m = LinkedHashMap::new();
+ fn collect(&self) -> Result<MapImpl<String, Value>> {
+ let mut m = MapImpl::new();
let uri: String = "the environment".into();
let separator = self.separator.as_deref().unwrap_or("");
diff --git a/src/file/format/hjson.rs b/src/file/format/hjson.rs
index a61afef..68b9c9c 100644
--- a/src/file/format/hjson.rs
+++ b/src/file/format/hjson.rs
@@ -1,19 +1,19 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn 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(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
}
}
@@ -30,7 +30,7 @@ fn from_hjson_value(uri: Option<&String>, value: &serde_hjson::Value) -> Value {
serde_hjson::Value::Bool(value) => Value::new(uri, ValueKind::Boolean(value)),
serde_hjson::Value::Object(ref table) => {
- let mut m = LinkedHashMap::new();
+ let mut m = MapImpl::new();
for (key, value) in table {
m.insert(key.clone(), from_hjson_value(uri, value));
diff --git a/src/file/format/ini.rs b/src/file/format/ini.rs
index 47f3499..b5f742d 100644
--- a/src/file/format/ini.rs
+++ b/src/file/format/ini.rs
@@ -1,20 +1,20 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
use ini::Ini;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
- let mut map: LinkedHashMap<String, Value> = LinkedHashMap::new();
+) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
+ let mut map: MapImpl<String, Value> = MapImpl::new();
let i = Ini::load_from_str(text)?;
for (sec, prop) in i.iter() {
match sec {
Some(sec) => {
- let mut sec_map: LinkedHashMap<String, Value> = LinkedHashMap::new();
+ let mut sec_map: MapImpl<String, Value> = MapImpl::new();
for (k, v) in prop.iter() {
sec_map.insert(
k.to_owned(),
diff --git a/src/file/format/json.rs b/src/file/format/json.rs
index a6a9443..c4895fb 100644
--- a/src/file/format/json.rs
+++ b/src/file/format/json.rs
@@ -1,19 +1,19 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn 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_json_value(uri, &serde_json::from_str(text)?);
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
}
}
@@ -34,7 +34,7 @@ fn from_json_value(uri: Option<&String>, value: &serde_json::Value) -> Value {
serde_json::Value::Bool(value) => Value::new(uri, ValueKind::Boolean(value)),
serde_json::Value::Object(ref table) => {
- let mut m = LinkedHashMap::new();
+ let mut m = MapImpl::new();
for (key, value) in table {
m.insert(key.clone(), from_json_value(uri, value));
diff --git a/src/file/format/json5.rs b/src/file/format/json5.rs
index 952b265..69432c0 100644
--- a/src/file/format/json5.rs
+++ b/src/file/format/json5.rs
@@ -1,7 +1,7 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::error::{ConfigError, Unexpected};
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
#[derive(serde::Deserialize, Debug)]
@@ -13,13 +13,13 @@ pub enum Val {
Float(f64),
String(String),
Array(Vec<Val>),
- Object(LinkedHashMap<String, Val>),
+ Object(MapImpl<String, Val>),
}
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
match json5_rs::from_str::<Val>(text)? {
Val::String(ref value) => Err(Unexpected::Str(value.clone())),
Val::Integer(value) => Err(Unexpected::Integer(value)),
@@ -29,7 +29,7 @@ pub fn parse(
Val::Null => Err(Unexpected::Unit),
Val::Object(o) => match from_json5_value(uri, Val::Object(o)).kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
},
}
.map_err(|err| ConfigError::invalid_root(uri, err))
diff --git a/src/file/format/mod.rs b/src/file/format/mod.rs
index 55d1c7a..df59ca6 100644
--- a/src/file/format/mod.rs
+++ b/src/file/format/mod.rs
@@ -2,9 +2,9 @@
// BUG: ? For some reason this doesn't do anything if I try and function scope this
#![allow(unused_mut)]
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
+use crate::map::MapImpl;
use crate::value::Value;
#[cfg(feature = "toml")]
@@ -62,8 +62,8 @@ pub enum FileFormat {
lazy_static! {
#[doc(hidden)]
// #[allow(unused_mut)] ?
- pub static ref ALL_EXTENSIONS: LinkedHashMap<FileFormat, Vec<&'static str>> = {
- let mut formats: LinkedHashMap<FileFormat, Vec<_>> = LinkedHashMap::new();
+ pub static ref ALL_EXTENSIONS: MapImpl<FileFormat, Vec<&'static str>> = {
+ let mut formats: MapImpl<FileFormat, Vec<_>> = MapImpl::new();
#[cfg(feature = "toml")]
formats.insert(FileFormat::Toml, vec!["toml"]);
@@ -107,7 +107,7 @@ impl FileFormat {
self,
uri: Option<&String>,
text: &str,
- ) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+ ) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
match self {
#[cfg(feature = "toml")]
FileFormat::Toml => toml::parse(uri, text),
diff --git a/src/file/format/ron.rs b/src/file/format/ron.rs
index a527d6f..769fd53 100644
--- a/src/file/format/ron.rs
+++ b/src/file/format/ron.rs
@@ -1,17 +1,17 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
let value = from_ron_value(uri, ron::from_str(text)?)?;
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
}
}
@@ -56,7 +56,7 @@ fn from_ron_value(
Ok((key, value))
})
- .collect::<Result<LinkedHashMap<_, _>, _>>()?;
+ .collect::<Result<MapImpl<_, _>, _>>()?;
ValueKind::Table(map)
}
diff --git a/src/file/format/toml.rs b/src/file/format/toml.rs
index 5468d97..a4e16b2 100644
--- a/src/file/format/toml.rs
+++ b/src/file/format/toml.rs
@@ -1,19 +1,19 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
// Parse a TOML value from the provided text
// TODO: Have a proper error fire if the root of a file is ever not a Table
let value = from_toml_value(uri, &toml::from_str(text)?);
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
}
}
@@ -25,7 +25,7 @@ fn from_toml_value(uri: Option<&String>, value: &toml::Value) -> Value {
toml::Value::Boolean(value) => Value::new(uri, value),
toml::Value::Table(ref table) => {
- let mut m = LinkedHashMap::new();
+ let mut m = MapImpl::new();
for (key, value) in table {
m.insert(key.clone(), from_toml_value(uri, value));
diff --git a/src/file/format/yaml.rs b/src/file/format/yaml.rs
index 246758a..f725b1f 100644
--- a/src/file/format/yaml.rs
+++ b/src/file/format/yaml.rs
@@ -1,16 +1,16 @@
-use linked_hash_map::LinkedHashMap;
use std::error::Error;
use std::fmt;
use std::mem;
use yaml_rust as yaml;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<MapImpl<String, Value>, Box<dyn Error + Send + Sync>> {
// Parse a YAML object from file
let mut docs = yaml::YamlLoader::load_from_str(text)?;
let root = match docs.len() {
@@ -26,7 +26,7 @@ pub fn parse(
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(LinkedHashMap::new()),
+ _ => Ok(MapImpl::new()),
}
}
@@ -40,7 +40,7 @@ fn from_yaml_value(uri: Option<&String>, value: &yaml::Yaml) -> Value {
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) => {
- let mut m = LinkedHashMap::new();
+ let mut m = MapImpl::new();
for (key, value) in table {
if let Some(k) = key.as_str() {
m.insert(k.to_owned(), from_yaml_value(uri, value));
diff --git a/src/file/mod.rs b/src/file/mod.rs
index 02fd51f..d5744f4 100644
--- a/src/file/mod.rs
+++ b/src/file/mod.rs
@@ -1,10 +1,10 @@
mod format;
pub mod source;
-use linked_hash_map::LinkedHashMap;
use std::path::{Path, PathBuf};
use crate::error::*;
+use crate::map::MapImpl;
use crate::source::Source;
use crate::value::Value;
@@ -99,7 +99,7 @@ where
Box::new((*self).clone())
}
- fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ fn collect(&self) -> Result<MapImpl<String, Value>> {
// Coerce the file contents to a string
let (uri, contents, format) = match self
.source
@@ -110,7 +110,7 @@ where
Err(error) => {
if !self.required {
- return Ok(LinkedHashMap::new());
+ return Ok(MapImpl::new());
}
return Err(error);
diff --git a/src/lib.rs b/src/lib.rs
index 87c82bc..511ddd8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -59,6 +59,7 @@ mod de;
mod env;
mod error;
mod file;
+mod map;
mod path;
mod ser;
mod source;
@@ -70,6 +71,7 @@ pub use crate::config::Config;
pub use crate::env::Environment;
pub use crate::error::ConfigError;
pub use crate::file::{File, FileFormat, FileSourceFile, FileSourceString};
+pub use crate::map::MapImpl;
pub use crate::source::AsyncSource;
pub use crate::source::Source;
pub use crate::value::Value;
diff --git a/src/map.rs b/src/map.rs
new file mode 100644
index 0000000..ae41155
--- /dev/null
+++ b/src/map.rs
@@ -0,0 +1,4 @@
+#[cfg(not(feature = "preserve_order"))]
+pub type MapImpl<K, V> = std::collections::HashMap<K, V>;
+#[cfg(feature = "preserve_order")]
+pub type MapImpl<K, V> = linked_hash_map::LinkedHashMap<K, V>;
diff --git a/src/path/mod.rs b/src/path/mod.rs
index b056467..8ce51f9 100644
--- a/src/path/mod.rs
+++ b/src/path/mod.rs
@@ -1,7 +1,7 @@
-use linked_hash_map::LinkedHashMap;
use std::str::FromStr;
use crate::error::*;
+use crate::map::MapImpl;
use crate::value::{Value, ValueKind};
mod parser;
@@ -135,7 +135,7 @@ impl Expression {
),
_ => {
- *value = LinkedHashMap::<String, Value>::new().into();