summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-03-28 18:13:08 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-07-10 15:37:45 +0200
commitdca0874d1dc89c341d1f17fbabca3ff6d17e48d5 (patch)
treeb99948eca4b966f079c61e2ee550c794aafb5834
parent8e8a9d9dea801dbc68324276f486deb512df08e3 (diff)
WIP Case sensitivity supportcase-sensitivity-support
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/config.rs29
-rw-r--r--src/de.rs19
-rw-r--r--src/value.rs10
3 files changed, 46 insertions, 12 deletions
diff --git a/src/config.rs b/src/config.rs
index b9c64b4..fa95063 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -14,6 +14,8 @@ use crate::value::{Table, Value};
/// A prioritized configuration repository. It maintains a set of
/// configuration sources, fetches values to populate those, and provides
/// them according to the source's priority.
+///
+/// By default, keys and enum variants are deserialized case sensitive, so "FOO" != "foo"
#[derive(Clone, Debug)]
pub struct Config {
defaults: HashMap<path::Expression, Value>,
@@ -22,6 +24,12 @@ pub struct Config {
/// Root of the cached configuration.
pub cache: Value,
+
+ /// Flag whether keys should be deserialized case-sensitive
+ pub(crate) keys_case_sensitive: bool,
+
+ /// Flag whether enum variants should be deserialized case-sensitive
+ pub(crate) enum_variants_case_sensitive: bool,
}
impl Default for Config {
@@ -31,23 +39,30 @@ impl Default for Config {
overrides: Default::default(),
sources: Default::default(),
cache: Value::new(None, Table::new()),
+ keys_case_sensitive: true,
+ enum_variants_case_sensitive: true,
}
}
}
impl Config {
- pub(crate) fn new(value: Value) -> Self {
- Config {
- cache: value,
- ..Default::default()
- }
- }
-
/// Creates new [`ConfigBuilder`] instance
pub fn builder() -> ConfigBuilder<DefaultState> {
ConfigBuilder::<DefaultState>::default()
}
+ pub fn with_keys_case_sensitive(mut self, b: bool) -> Self {
+ self.keys_case_sensitive = b;
+ self.cache.keys_case_sensitive = b;
+ self
+ }
+
+ pub fn with_enum_variants_case_sensitive(mut self, b: bool) -> Self {
+ self.enum_variants_case_sensitive = b;
+ self.cache.enum_variants_case_sensitive = b;
+ self
+ }
+
/// Merge in a configuration property source.
#[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn merge<T>(&mut self, source: T) -> Result<&mut Config>
diff --git a/src/de.rs b/src/de.rs
index a7a6fb4..7af816c 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -23,7 +23,7 @@ impl<'de> de::Deserializer<'de> for Value {
ValueKind::Float(f) => visitor.visit_f64(f),
ValueKind::String(s) => visitor.visit_string(s),
ValueKind::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
- ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map)),
+ ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map, self.keys_case_sensitive, self.enum_variants_case_sensitive)),
}
}
@@ -128,6 +128,7 @@ impl<'de> de::Deserializer<'de> for Value {
V: de::Visitor<'de>,
{
visitor.visit_enum(EnumAccess {
+ variants_case_sensitive: self.enum_variants_case_sensitive,
value: self,
name,
variants,
@@ -196,12 +197,16 @@ impl<'de> de::SeqAccess<'de> for SeqAccess {
struct MapAccess {
elements: VecDeque<(String, Value)>,
+ keys_case_sensitive: bool,
+ enum_variants_case_sensitive: bool,
}
impl MapAccess {
- fn new(table: HashMap<String, Value>) -> Self {
+ fn new(table: HashMap<String, Value>, keys_case_sensitive: bool, enum_variants_case_sensitive: bool) -> Self {
MapAccess {
elements: table.into_iter().collect(),
+ keys_case_sensitive,
+ enum_variants_case_sensitive,
}
}
}
@@ -214,7 +219,9 @@ impl<'de> de::MapAccess<'de> for MapAccess {
K: de::DeserializeSeed<'de>,
{
if let Some(&(ref key_s, _)) = self.elements.front() {
- let key_de = Value::new(None, key_s as &str);
+ let mut key_de = Value::new(None, key_s as &str);
+ key_de.keys_case_sensitive = self.keys_case_sensitive;
+ key_de.enum_variants_case_sensitive = self.enum_variants_case_sensitive;
let key = de::DeserializeSeed::deserialize(seed, key_de)?;
Ok(Some(key))
@@ -236,13 +243,14 @@ struct EnumAccess {
value: Value,
name: &'static str,
variants: &'static [&'static str],
+ variants_case_sensitive: bool,
}
impl EnumAccess {
fn variant_deserializer(&self, name: &str) -> Result<StrDeserializer> {
self.variants
.iter()
- .find(|&&s| s == name)
+ .find(|&&s| s == name || (!self.variants_case_sensitive && s.eq_ignore_ascii_case(name)))
.map(|&s| StrDeserializer(s))
.ok_or_else(|| self.no_constructor_error(name))
}
@@ -349,7 +357,7 @@ impl<'de> de::Deserializer<'de> for Config {
ValueKind::Float(f) => visitor.visit_f64(f),
ValueKind::String(s) => visitor.visit_string(s),
ValueKind::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
- ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map)),
+ ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map, self.keys_case_sensitive, self.enum_variants_case_sensitive)),
}
}
@@ -450,6 +458,7 @@ impl<'de> de::Deserializer<'de> for Config {
value: self.cache,
name,
variants,
+ variants_case_sensitive: self.enum_variants_case_sensitive,
})
}
diff --git a/src/value.rs b/src/value.rs
index 8db5fcc..69cd07a 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -136,6 +136,12 @@ pub struct Value {
/// Underlying kind of the configuration value.
pub kind: ValueKind,
+
+ /// Flag whether keys should be deserialized case-sensitive
+ pub(crate) keys_case_sensitive: bool,
+
+ /// Flag whether enum variants should be deserialized case-sensitive
+ pub(crate) enum_variants_case_sensitive: bool,
}
impl Value {
@@ -147,6 +153,8 @@ impl Value {
Value {
origin: origin.cloned(),
kind: kind.into(),
+ keys_case_sensitive: true,
+ enum_variants_case_sensitive: true,
}
}
@@ -533,6 +541,8 @@ where
Value {
origin: None,
kind: value.into(),
+ keys_case_sensitive: true,
+ enum_variants_case_sensitive: true,
}
}
}