use std::any::Any;
use std::fmt::Debug;
use crate::store::item::{Key, Value};
use crate::store::{Store, StoreIterable, StoreKeys, StoreMut, StoreValues};
pub trait Collection<K, V>: Any + Debug {
fn get(&self, key: &K) -> Option<&V>;
fn contains_key(&self, id: &K) -> bool;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn insert(&mut self, key: K, value: V) -> Option<V>;
fn remove(&mut self, key: &K) -> Option<V>;
fn remove_entry(&mut self, key: &K) -> Option<(K, V)>;
fn clear(&mut self);
fn iter(&self) -> Iter<'_, K, V>;
fn keys(&self) -> Keys<'_, K>;
fn values(&self) -> Values<'_, V>;
}
impl<K, V> dyn Collection<K, V> {
#[inline]
#[must_use]
pub fn downcast_ref<T>(&self) -> Option<&T>
where
T: Collection<K, V> + Any,
{
(self as &dyn Any).downcast_ref()
}
#[inline]
#[must_use]
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
where
T: Collection<K, V> + Any,
{
(self as &mut dyn Any).downcast_mut()
}
}
impl<'a, K, V> IntoIterator for &'a dyn Collection<K, V>
where
K: Key,
V: Value,
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<K, V, S> Collection<K, V> for S
where
K: Key,
V: Value,
S: Any + Debug,
S: Store<K, V>
+ StoreMut<K, V>
+ StoreIterable<K, V>
+ StoreKeys<K, V>
+ StoreValues<K, V>,
{
#[inline]
fn get(&self, id: &K) -> Option<&V> {
Store::get(self, id)
}
#[inline]
fn contains_key(&self, id: &K) -> bool {
Store::contains_key(self, id)
}
#[inline]
fn len(&self) -> usize {
Store::len(self)
}
#[inline]
fn is_empty(&self) -> bool {
Store::is_empty(self)
}
#[inline]
fn insert(&mut self, key: K, value: V) -> Option<V> {
StoreMut::insert(self, key, value)
}
#[inline]
fn remove(&mut self, key: &K) -> Option<V> {
StoreMut::remove(self, key)
}
#[inline]
fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
StoreMut::remove_entry(self, key)
}
#[inline]
fn clear(&mut self) {
StoreMut::clear(self);
}
#[inline]
fn iter(&self) -> Iter<'_, K, V> {
Box::new(StoreIterable::iter(self))
}
#[inline]
fn keys(&self) -> Keys<'_, K> {
Box::new(StoreKeys::keys(self))
}
#[inline]
fn values(&self) -> Values<'_, V> {
Box::new(StoreValues::values(self))
}
}
pub type Iter<'a, K, V> = Box<dyn Iterator<Item = (&'a K, &'a V)> + 'a>;
pub type Keys<'a, K> = Box<dyn Iterator<Item = &'a K> + 'a>;
pub type Values<'a, V> = Box<dyn Iterator<Item = &'a V> + 'a>;