summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs24
-rw-r--r--src/tests/mod.rs38
2 files changed, 55 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7d90ec4..77990bf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,7 +5,6 @@
#![warn(clippy::redundant_closure_for_method_calls)]
extern crate alloc;
-use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::string::String;
use alloc::sync::Arc;
@@ -698,7 +697,10 @@ impl Configuration {
let start_idx = self.subkey_start_idx(key);
let end_idx = self.subkey_end_idx(key);
Configuration {
- items: self.items[start_idx..end_idx].to_owned(),
+ items: self.items[start_idx..end_idx]
+ .iter()
+ .map(|(k, v)| (k[key.len() + 1..].into(), v.clone()))
+ .collect(),
}
}
@@ -855,17 +857,25 @@ impl Configuration {
/// Get value associated with `key`, and parse it as a comma-separated list, or else use `default`.
///
+ /// If you want `default = []`, use [`Self::get_list_or_empty`] instead
+ /// (this method will be cumbersome to use since Rust can't infer the type of `[]`).
+ ///
/// Commas in list entries can be escaped with `\,`.
///
- /// `default` can be anything that can be converted into an iterator of strings,
- /// e.g. `Vec<&str>`, `Vec<String>`, `&[&str]`, etc.
+ /// `default` can be any iterable-of-strings
+ /// (e.g. `&[&str]`, `Vec<String>`, etc.).
pub fn get_list_or_default<L>(&self, key: &str, default: L) -> Vec<String>
where
L: IntoIterator,
- L::Item: AsRef<str>,
+ String: From<L::Item>,
{
self.get_list(key)
- .unwrap_or_else(|| default.into_iter().map(|s| s.as_ref().to_owned()).collect())
+ .unwrap_or_else(|| default.into_iter().map(String::from).collect())
+ }
+ /// Get value associated with `key`, and parse it as a comma-separated list, or else use `[]`.
+ pub fn get_list_or_empty(&self, key: &str) -> Vec<String> {
+ let empty: [&'static str; 0] = [];
+ self.get_list_or_default(key, empty)
}
/// Merge `conf` into `self`, preferring values in `conf`.
@@ -894,7 +904,7 @@ impl Configuration {
}
}
-/// Opaque type returned by [`<&Configuration>::into_iter`].
+/// Opaque type returned by [`Configuration::iter`].
#[derive(Clone, Debug)]
pub struct ConfigurationIter<'a>(core::slice::Iter<'a, (Box<str>, Value)>);
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index 97a3a29..644c131 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -2,6 +2,8 @@ mod errors;
mod locations;
mod parsing;
+use crate::Configuration;
+
fn do_tests_in_dir(
dir: &str,
ext: &str,
@@ -32,3 +34,39 @@ fn do_tests_in_dir(
panic!("Error: {e}");
}
}
+
+#[test]
+fn misc() {
+ let conf = Configuration::load(
+ "<test configuration>",
+ "
+a = yes
+[foo]
+x = 5
+bar.y = 6
+"
+ .as_bytes(),
+ )
+ .unwrap();
+ // test section
+ assert_eq!(conf.section("foo").get("x"), Some("5"));
+ assert_eq!(conf.section("foo").get("bar.y"), Some("6"));
+ assert_eq!(conf.section("foo.bar").get("y"), Some("6"));
+ assert_eq!(conf.section("fob").get("x"), None);
+ // test get_or_default
+ assert_eq!(conf.get_or_default("foo.x", ""), "5");
+ assert_eq!(conf.get_or_default("foo.y", ""), "");
+ assert_eq!(conf.get_int_or_default("foo.x", 0).unwrap(), 5);
+ assert_eq!(conf.get_int_or_default("foo.y", 0).unwrap(), 0);
+ assert_eq!(conf.get_float_or_default("foo.x", 0.0).unwrap(), 5.0);
+ assert_eq!(conf.get_float_or_default("foo.y", 0.0).unwrap(), 0.0);
+ assert!(conf.get_bool_or_default("a", false).unwrap());
+ assert!(!conf.get_bool_or_default("aa", false).unwrap());
+ assert_eq!(conf.get_list_or_default("a", ["a"]), ["yes"]);
+ assert_eq!(conf.get_list_or_default("aa", ["a"]), ["a"]);
+ assert_eq!(conf.get_list_or_empty("a"), ["yes"]);
+ assert!(conf.get_list_or_empty("aa").is_empty());
+ let mut keys: Vec<_> = conf.keys().collect();
+ keys.sort();
+ assert_eq!(keys, ["a", "foo"]);
+}