use crate::storage::{Counted, Dequeue, DequeueError, IterableMap, KeyFor};
use core::marker::PhantomData;
pub trait Queue {
type Value;
type Error: DequeueError;
type OutputError: From<Self::Error>;
fn dequeue() -> Result<Option<Self::Value>, Self::OutputError>;
fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(f: F);
fn queue(value: Self::Value) -> Result<(), Self::OutputError>;
fn clear();
fn requeue(value: Self::Value) -> Result<(), Self::OutputError>;
}
pub struct QueueImpl<T, OutputError, KeyGen>(PhantomData<(T, OutputError, KeyGen)>)
where
T: Dequeue,
OutputError: From<T::Error>,
KeyGen: KeyFor<Key = T::Key, Value = T::Value>;
impl<T, OutputError, KeyGen> Queue for QueueImpl<T, OutputError, KeyGen>
where
T: Dequeue,
OutputError: From<T::Error>,
T::Error: DequeueError,
KeyGen: KeyFor<Key = T::Key, Value = T::Value>,
{
type Value = T::Value;
type Error = T::Error;
type OutputError = OutputError;
fn dequeue() -> Result<Option<Self::Value>, Self::OutputError> {
T::pop_front().map_err(Into::into)
}
fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(f: F) {
T::mutate_values(f)
}
fn queue(value: Self::Value) -> Result<(), Self::OutputError> {
let key = KeyGen::key_for(&value);
T::push_back(key, value).map_err(Into::into)
}
fn clear() {
T::clear()
}
fn requeue(value: Self::Value) -> Result<(), Self::OutputError> {
let key = KeyGen::key_for(&value);
T::push_front(key, value).map_err(Into::into)
}
}
impl<T, OutputError, KeyGen> Counted for QueueImpl<T, OutputError, KeyGen>
where
T: Dequeue + Counted,
OutputError: From<T::Error>,
KeyGen: KeyFor<Key = T::Key, Value = T::Value>,
{
type Length = T::Length;
fn len() -> Self::Length {
T::len()
}
}
pub struct QueueDrainIter<T, OutputError>(T::DrainIter, PhantomData<OutputError>)
where
T: Dequeue + IterableMap<Result<T::Value, T::Error>>,
OutputError: From<T::Error>;
impl<T, OutputError> Iterator for QueueDrainIter<T, OutputError>
where
T: Dequeue + IterableMap<Result<T::Value, T::Error>>,
OutputError: From<T::Error>,
{
type Item = Result<T::Value, OutputError>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|res| res.map_err(Into::into))
}
}
pub struct QueueIter<T, OutputError>(T::Iter, PhantomData<OutputError>)
where
T: Dequeue + IterableMap<Result<T::Value, T::Error>>,
OutputError: From<T::Error>;
impl<T, OutputError> Iterator for QueueIter<T, OutputError>
where
T: Dequeue + IterableMap<Result<T::Value, T::Error>>,
OutputError: From<T::Error>,
{
type Item = Result<T::Value, OutputError>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|res| res.map_err(Into::into))
}
}
impl<T, OutputError, KeyGen> IterableMap<Result<T::Value, OutputError>>
for QueueImpl<T, OutputError, KeyGen>
where
T: Dequeue + IterableMap<Result<T::Value, T::Error>>,
OutputError: From<T::Error>,
KeyGen: KeyFor<Key = T::Key, Value = T::Value>,
{
type DrainIter = QueueDrainIter<T, OutputError>;
type Iter = QueueIter<T, OutputError>;
fn drain() -> Self::DrainIter {
QueueDrainIter(T::drain(), PhantomData::<OutputError>)
}
fn iter() -> Self::Iter {
QueueIter(T::iter(), PhantomData::<OutputError>)
}
}