use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{BuildHasher, Hash};
use crate::{bag, entry, BagDelta, EntryDelta};
pub trait Unordered: Sized {
type Delta: Default;
fn diff(old: Self, new: Self) -> Option<Self::Delta>;
fn apply(&mut self, delta: Self::Delta);
}
impl<T, S> Unordered for HashSet<T, S>
where
T: Hash + Eq,
S: BuildHasher,
{
type Delta = BagDelta<T>;
fn diff(old: Self, new: Self) -> Option<BagDelta<T>> {
let delta = bag::diff(old, new);
if delta.is_empty() {
None
} else {
Some(delta)
}
}
fn apply(&mut self, delta: BagDelta<T>) {
bag::apply(self, delta)
}
}
impl<T> Unordered for BTreeSet<T>
where
T: Ord,
{
type Delta = BagDelta<T>;
fn diff(old: Self, new: Self) -> Option<BagDelta<T>> {
let delta = bag::diff(old, new);
if delta.is_empty() {
None
} else {
Some(delta)
}
}
fn apply(&mut self, delta: BagDelta<T>) {
bag::apply(self, delta)
}
}
impl<K, V, S> Unordered for HashMap<K, V, S>
where
K: Hash + Eq,
V: PartialEq,
S: BuildHasher,
{
type Delta = EntryDelta<K, V>;
fn diff(old: Self, new: Self) -> Option<EntryDelta<K, V>> {
let delta = entry::diff(old, new);
if delta.is_empty() {
None
} else {
Some(delta)
}
}
fn apply(&mut self, delta: EntryDelta<K, V>) {
entry::apply(self, delta)
}
}
impl<K, V> Unordered for BTreeMap<K, V>
where
K: Ord,
V: PartialEq,
{
type Delta = EntryDelta<K, V>;
fn diff(old: Self, new: Self) -> Option<EntryDelta<K, V>> {
let delta = entry::diff(old, new);
if delta.is_empty() {
None
} else {
Some(delta)
}
}
fn apply(&mut self, delta: EntryDelta<K, V>) {
entry::apply(self, delta)
}
}