use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::Hash;
use std::marker::PhantomData;
use crate::interner::Interner;
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(default, rename_all = "camelCase")
)]
pub struct CollectionStore<CollectionMap, ReverseLookup, ReverseSet, Interner, K, C, IK, IV>
where
CollectionMap: MapCollection<Key = K, Value = C>,
ReverseLookup: MapCollection<Key = IK, Value = ReverseSet>,
ReverseSet: KeyCollection<K> + FlatCollection<K>,
Interner: crate::interner::Interner<IK, IV>,
K: Copy,
C: KeyCollection<IK>,
IK: Copy,
IV: Clone,
{
pub collections: CollectionMap,
pub reverse: ReverseLookup,
pub inner: Interner,
_interned_value: PhantomData<IV>,
}
impl<CollectionMap, ReverseLookup, ReverseSet, Inner, K, C, IK, IV> CollectionInterner<K, C, IK, IV>
for CollectionStore<CollectionMap, ReverseLookup, ReverseSet, Inner, K, C, IK, IV>
where
CollectionMap: MapCollection<Key = K, Value = C>,
ReverseLookup: MapCollection<Key = IK, Value = ReverseSet>,
ReverseSet: KeyCollection<K> + FlatCollection<K>,
Inner: Interner<IK, IV>,
K: Copy,
C: KeyCollection<IK> + Clone,
IK: Copy,
IV: Clone,
{
fn get(&self, key: K) -> Option<&C> {
self.collections.collection_value(&key)
}
fn get_mut(&mut self, key: K) -> Option<&mut C> {
self.collections.collection_value_mut(&key)
}
fn with_inner(&self, inner: IK) -> impl Iterator<Item = K> {
self.reverse
.collection_value(&inner)
.into_iter()
.flat_map(|cols| cols.collection_keys())
}
fn with_inner_value(&self, inner: &IV) -> impl Iterator<Item = K> {
self.interner()
.get_key(inner)
.map(|inner| self.with_inner(inner))
.into_iter()
.flatten()
}
fn contains(&self, key: K) -> bool {
self.collections.collection_contains(&key)
}
fn interner(&self) -> &impl Interner<IK, IV> {
&self.inner
}
fn interner_mut(&mut self) -> &mut impl Interner<IK, IV> {
&mut self.inner
}
fn is_empty(&self) -> bool {
self.collections.collection_is_empty()
}
fn keys(&self) -> impl Iterator<Item = K> {
self.collections.collection_keys()
}
fn len(&self) -> usize {
self.collections.collection_len()
}
fn remove(&mut self, key: K) -> bool {
match self.collections.remove_collection_value(&key) {
Some(coll) => {
coll.collection_keys().for_each(|inner_key| {
self.reverse
.collection_value_mut(&inner_key)
.map(|lookup| lookup.remove_collection_key(&key));
});
true
}
None => false,
}
}
}
pub trait CollectionInterner<K: Copy, C: Clone + KeyCollection<IK>, IK: Copy, IV: Clone> {
fn interner(&self) -> &impl Interner<IK, IV>;
fn interner_mut(&mut self) -> &mut impl Interner<IK, IV>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn keys(&self) -> impl Iterator<Item = K>;
fn get(&self, key: K) -> Option<&C>;
fn get_mut(&mut self, key: K) -> Option<&mut C>;
fn with_inner(&self, inner: IK) -> impl Iterator<Item = K>;
fn with_inner_value(&self, inner: &IV) -> impl Iterator<Item = K>;
fn contains(&self, key: K) -> bool;
fn remove(&mut self, key: K) -> bool;
}
pub trait KeyCollection<K> {
fn collection_keys(&self) -> impl Iterator<Item = K>;
fn collection_contains(&self, key: &K) -> bool;
fn collection_len(&self) -> usize;
fn collection_is_empty(&self) -> bool {
self.collection_len() == 0
}
}
impl<K: Clone + PartialEq> KeyCollection<K> for Option<K> {
fn collection_keys(&self) -> impl Iterator<Item = K> {
self.iter().cloned()
}
fn collection_contains(&self, key: &K) -> bool {
self.as_ref() == Some(key)
}
fn collection_len(&self) -> usize {
match self {
Some(_) => 1,
None => 0,
}
}
fn collection_is_empty(&self) -> bool {
self.is_none()
}
}
impl<K: Clone + PartialEq + Ord> KeyCollection<K> for BTreeSet<K> {
fn collection_keys(&self) -> impl Iterator<Item = K> {
self.iter().cloned()
}
fn collection_contains(&self, key: &K) -> bool {
self.contains(key)
}
fn collection_len(&self) -> usize {
self.len()
}
}
impl<K: Clone + Ord, IV> KeyCollection<K> for BTreeMap<K, IV> {
fn collection_keys(&self) -> impl Iterator<Item = K> {
self.keys().cloned()
}
fn collection_contains(&self, key: &K) -> bool {
BTreeMap::contains_key(self, key)
}
fn collection_len(&self) -> usize {
self.len()
}
}
impl<K: Clone + Hash + Eq> KeyCollection<K> for HashSet<K> {
fn collection_keys(&self) -> impl Iterator<Item = K> {
self.iter().cloned()
}
fn collection_contains(&self, key: &K) -> bool {
self.contains(key)
}
fn collection_len(&self) -> usize {
self.len()
}
}
impl<K: Clone + Hash + Eq, IV> KeyCollection<K> for HashMap<K, IV> {
fn collection_keys(&self) -> impl Iterator<Item = K> {
self.keys().cloned()
}
fn collection_contains(&self, key: &K) -> bool {
self.contains_key(key)
}
fn collection_len(&self) -> usize {
self.len()
}
}
pub trait FlatCollection<K: Clone>: KeyCollection<K> {
fn insert_collection_key(&mut self, key: K) -> Option<K>;
fn remove_collection_key(&mut self, key: &K) -> Option<K>;
}
impl<K: Clone + PartialEq> FlatCollection<K> for Option<K> {
fn insert_collection_key(&mut self, key: K) -> Option<K> {
self.replace(key)
}
fn remove_collection_key(&mut self, key: &K) -> Option<K> {
if self.as_ref() == Some(key) {
self.take()
} else {
None
}
}
}
impl<IK: Clone + Clone + Ord> FlatCollection<IK> for BTreeSet<IK> {
fn insert_collection_key(&mut self, key: IK) -> Option<IK> {
if self.insert(key.clone()) {
None
} else {
Some(key)
}
}
fn remove_collection_key(&mut self, key: &IK) -> Option<IK> {
if self.remove(key) {
Some(key.clone())
} else {
None
}
}
}
impl<IK: Clone + Hash + Eq> FlatCollection<IK> for HashSet<IK> {
fn insert_collection_key(&mut self, key: IK) -> Option<IK> {
if self.insert(key.clone()) {
None
} else {
Some(key)
}
}
fn remove_collection_key(&mut self, key: &IK) -> Option<IK> {
if self.remove(key) {
Some(key.clone())
} else {
None
}
}
}
pub trait MapCollection: KeyCollection<Self::Key> {
type Key: Clone;
type Value;
fn collection_value(&self, key: &Self::Key) -> Option<&Self::Value>;
fn collection_value_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value>;
fn insert_collection_value(
&mut self,
key: Self::Key,
value: Self::Value,
) -> Option<Self::Value>;
fn remove_collection_value(&mut self, key: &Self::Key) -> Option<Self::Value>;
}
impl<K: Clone + Ord, V> MapCollection for BTreeMap<K, V> {
type Key = K;
type Value = V;
fn collection_value(&self, key: &K) -> Option<&V> {
self.get(key)
}
fn collection_value_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
self.get_mut(key)
}
fn insert_collection_value(&mut self, key: K, value: V) -> Option<V> {
self.insert(key, value)
}
fn remove_collection_value(&mut self, key: &K) -> Option<V> {
self.remove(key)
}
}
impl<K: Clone + Hash + Eq, V> MapCollection for HashMap<K, V> {
type Key = K;
type Value = V;
fn collection_value(&self, key: &K) -> Option<&V> {
self.get(key)
}
fn collection_value_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
self.get_mut(key)
}
fn insert_collection_value(&mut self, key: K, value: V) -> Option<V> {
self.insert(key, value)
}
fn remove_collection_value(&mut self, key: &K) -> Option<V> {
self.remove(key)
}
}