use crate::{Optionable, OptionableConvert};
pub fn merge_append_not_present<TARGET, OTHER, T>(target: &mut TARGET, other: OTHER)
where
TARGET: Extend<T>,
for<'a> &'a TARGET: IntoIterator<Item = &'a T>,
OTHER: IntoIterator<Item = T>,
T: PartialEq,
{
for el_other in other {
if !target.into_iter().any(|el_target| &el_other == el_target) {
target.extend(Some(el_other));
}
}
}
pub fn merge_append_not_present_option_wrapped<TARGET, OTHER, T>(
target: &mut Option<TARGET>,
other: Option<OTHER>,
) where
TARGET: Extend<T>,
for<'a> &'a TARGET: IntoIterator<Item = &'a T>,
OTHER: IntoIterator<Item = T> + Into<TARGET>,
T: PartialEq,
{
if let Some(other) = other {
if let Some(target) = target {
merge_append_not_present(target, other);
} else {
*target = Some(other.into());
}
}
}
pub fn try_merge_optioned_set<TARGET, OTHER, T>(
target: &mut TARGET,
other: OTHER,
) -> Result<(), crate::Error>
where
TARGET: Extend<T>,
for<'a> &'a TARGET: IntoIterator<Item = &'a T>,
OTHER: IntoIterator<Item = T::Optioned>,
T: OptionableConvert + PartialEq,
T::Optioned: Sized,
{
for el_other in other {
let el_other = T::try_from_optioned(el_other)?;
if !target.into_iter().any(|el_target| &el_other == el_target) {
target.extend(Some(el_other));
}
}
Ok(())
}
pub trait MapKeysEq {
fn keys_eq(&self, other: &Self) -> bool;
}
pub trait OptionableMapKeysEq: Optionable {
fn keys_eq(&self, other: &Self::Optioned) -> bool;
}
pub fn try_merge_optioned_map<TARGET, OTHER, T>(
target: &mut TARGET,
other: OTHER,
) -> Result<(), crate::Error>
where
TARGET: Extend<T>,
for<'a> &'a mut TARGET: IntoIterator<Item = &'a mut T>,
OTHER: IntoIterator<Item = T::Optioned>,
T: OptionableConvert + OptionableMapKeysEq,
T::Optioned: Sized,
{
for el_other in other {
if let Some(el_target) = target
.into_iter()
.find(|el_target| el_target.keys_eq(&el_other))
{
el_target.merge(el_other)?;
} else {
target.extend(Some(T::try_from_optioned(el_other)?));
}
}
Ok(())
}
#[cfg(feature = "std")]
#[cfg(test)]
mod test {
#[test]
fn merge_set() {
let mut target = vec![0, 1, 2];
super::try_merge_optioned_set(&mut target, vec![3]).unwrap();
assert_eq!(&target, &vec![0, 1, 2, 3]);
super::try_merge_optioned_set(&mut target, vec![0, 2, 4, 6, 8]).unwrap();
assert_eq!(&target, &vec![0, 1, 2, 3, 4, 6, 8]);
super::try_merge_optioned_set(&mut target, vec![0, 5, 9]).unwrap();
assert_eq!(&target, &vec![0, 1, 2, 3, 4, 6, 8, 5, 9]);
}
}