use crate::source::Source;
use crate::item::{SourceLocation, StringItem, Value};
use crate::confpath::ConfPath;
use std::rc::Rc;
use std::collections::HashMap;
use std::fmt;
#[derive(Debug)]
pub struct DefaultSourceLocation {
source: String
}
impl DefaultSourceLocation {
fn new(source: &str) -> Rc<Self> {
Rc::new(Self {
source: source.to_owned()
})
}
}
impl fmt::Display for DefaultSourceLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "default from {}", self.source)
}
}
impl SourceLocation for DefaultSourceLocation {}
pub struct Defaults {
items: HashMap<ConfPath, StringItem>
}
impl Defaults {
pub fn default() -> Box<Self> {
Box::new(Self {
items: HashMap::default()
})
}
fn get_item(&mut self, key: ConfPath) -> &mut StringItem {
self.items.entry(key.clone()).or_insert_with(|| StringItem::new(key))
}
pub fn empty(&mut self, key: ConfPath) {
self.get_item(key).clear();
}
pub fn set(&mut self, key: ConfPath, value: &str, source: &str) {
self.get_item(key).clear().push(Value::new(value.to_owned(), DefaultSourceLocation::new(source)));
}
pub fn put(&mut self, key: ConfPath, value: &str, source: &str) {
self.get_item(key).push(Value::new(value.to_owned(), DefaultSourceLocation::new(source)));
}
}
impl Source for Defaults {
fn get(&self, key: ConfPath) -> Option<StringItem> {
self.items.get(&key).cloned()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Config;
use crate::ConfPath;
use crate::error::ConfigError;
use crate::item::ValueExtractor;
#[test]
fn defaults() {
let mut c = Config::default();
let mut d = Defaults::default();
d.set(ConfPath::from(&["testA"]), "AaA", "sourceA");
d.set(ConfPath::from(&["testB"]), "BbB", "sourceB.1");
d.put(ConfPath::from(&["testB"]), "bBb", "sourceB.2");
d.set(ConfPath::from(&["testC"]), "cCc", "sourceC.1");
d.empty(ConfPath::from(&["testC"]));
d.put(ConfPath::from(&["testC"]), "CcC", "sourceC.2");
d.set(ConfPath::from(&["testD"]), "dDd", "sourceD.1");
d.put(ConfPath::from(&["testD"]), "ddD", "sourceD.2");
d.set(ConfPath::from(&["testD"]), "DdD", "sourceD.3");
d.put(ConfPath::from(&["testE"]), "EeE", "sourceE");
c.add_source(d);
assert_eq!((c.get(ConfPath::from(&["testA"])).value() as Result<String, ConfigError>).unwrap(), "AaA");
assert_eq!((c.get(ConfPath::from(&["testB"])).values(..) as Result<Vec<String>, ConfigError>).unwrap(), ["BbB", "bBb"]);
assert_eq!((c.get(ConfPath::from(&["testC"])).value() as Result<String, ConfigError>).unwrap(), "CcC");
assert_eq!((c.get(ConfPath::from(&["testD"])).value() as Result<String, ConfigError>).unwrap(), "DdD");
assert_eq!((c.get(ConfPath::from(&["testE"])).value() as Result<String, ConfigError>).unwrap(), "EeE");
}
}