use crate::config::{ConfigError, PartialConfig};
use std::{
collections::{BTreeMap, BTreeSet, HashMap, HashSet},
hash::Hash,
};
pub type Merger<Val, Ctx> = Box<dyn FnOnce(Val, Val, &Ctx) -> Result<(), ConfigError>>;
pub fn discard<T, C>(_: T, _: T, _: &C) -> Result<Option<T>, ConfigError> {
Ok(None)
}
pub fn preserve<T, C>(prev: T, _: T, _: &C) -> Result<Option<T>, ConfigError> {
Ok(Some(prev))
}
pub fn replace<T, C>(_: T, next: T, _: &C) -> Result<Option<T>, ConfigError> {
Ok(Some(next))
}
pub fn append_vec<T, C>(
mut prev: Vec<T>,
next: Vec<T>,
_: &C,
) -> Result<Option<Vec<T>>, ConfigError> {
prev.extend(next);
Ok(Some(prev))
}
pub fn prepend_vec<T, C>(prev: Vec<T>, next: Vec<T>, _: &C) -> Result<Option<Vec<T>>, ConfigError> {
let mut new = vec![];
new.extend(next);
new.extend(prev);
Ok(Some(new))
}
pub fn merge_btreemap<K, V, C>(
mut prev: BTreeMap<K, V>,
next: BTreeMap<K, V>,
_: &C,
) -> Result<Option<BTreeMap<K, V>>, ConfigError>
where
K: Eq + Hash + Ord,
{
for (key, value) in next {
prev.insert(key, value);
}
Ok(Some(prev))
}
pub fn merge_btreeset<T, C>(
mut prev: BTreeSet<T>,
next: BTreeSet<T>,
_: &C,
) -> Result<Option<BTreeSet<T>>, ConfigError>
where
T: Eq + Hash + Ord,
{
for item in next {
prev.insert(item);
}
Ok(Some(prev))
}
pub fn merge_hashmap<K, V, C>(
mut prev: HashMap<K, V>,
next: HashMap<K, V>,
_: &C,
) -> Result<Option<HashMap<K, V>>, ConfigError>
where
K: Eq + Hash,
{
for (key, value) in next {
prev.insert(key, value);
}
Ok(Some(prev))
}
pub fn merge_hashset<T, C>(
mut prev: HashSet<T>,
next: HashSet<T>,
_: &C,
) -> Result<Option<HashSet<T>>, ConfigError>
where
T: Eq + Hash,
{
for item in next {
prev.insert(item);
}
Ok(Some(prev))
}
pub fn merge_partial<T: PartialConfig>(
mut prev: T,
next: T,
context: &T::Context,
) -> Result<Option<T>, ConfigError> {
prev.merge(context, next)?;
Ok(Some(prev))
}