dyn_clone::clone_trait_object!(<T> Database<T>);
pub trait Database<T>: dyn_clone::DynClone + Send + Sync {
fn get(&mut self, name: &str) -> Option<T>;
fn len(&self) -> usize;
fn iter(&'_ self) -> DatabaseIter<'_, T>;
fn values(&'_ self) -> DatabaseValues<'_, T>;
}
pub struct DatabaseIter<'a, T> {
pub(crate) inner: Box<dyn Database<T>>,
pub(crate) names_iter: Box<dyn DoubleEndedIterator<Item = &'a str> + 'a>,
}
impl<'a, T> Iterator for DatabaseIter<'a, T> {
type Item = (&'a str, T);
fn next(&mut self) -> Option<Self::Item> {
let n = self.names_iter.next()?;
let v = self.inner.get(n)?;
Some((n, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.inner.len();
(size, Some(size))
}
}
pub struct DatabaseValues<'a, T> {
pub(crate) inner: Box<dyn Database<T>>,
pub(crate) names_iter: Box<dyn DoubleEndedIterator<Item = &'a str> + 'a>,
}
impl<'a, T> DatabaseValues<'a, T> {
pub fn names(self) -> Vec<&'a str> {
self.names_iter.collect()
}
}
impl<'a, T> Iterator for DatabaseValues<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.names_iter.next().and_then(|n| self.inner.get(n))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.inner.len();
(size, Some(size))
}
}
impl<'a, T> DoubleEndedIterator for DatabaseValues<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.names_iter.next_back().and_then(|n| self.inner.get(n))
}
}
impl<'a, T> ExactSizeIterator for DatabaseValues<'a, T> {}