use super::{Storage, StorageError};
use crate::runtime::{ScheduleError, Scheduler, TaskQueue};
use core::num::NonZeroUsize;
#[derive(Debug)]
pub enum StorageCommand {
Put { key: Vec<u8>, value: Vec<u8> },
Delete { key: Vec<u8> },
}
pub struct StorageWorkQueue {
queue: TaskQueue<StorageCommand>,
}
impl StorageWorkQueue {
pub fn new(capacity: NonZeroUsize) -> Self {
Self {
queue: TaskQueue::new(capacity),
}
}
pub fn len(&self) -> usize {
self.queue.len()
}
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
pub fn capacity(&self) -> usize {
self.queue.capacity()
}
pub fn enqueue(&mut self, command: StorageCommand) -> Result<(), StorageCommand> {
self.queue.try_push(command).map_err(|error| match error {
crate::runtime::QueuePushError::Full(command) => command,
})
}
pub fn dispatch_next(
&mut self,
scheduler: &Scheduler,
store: &mut dyn Storage,
) -> Option<Result<Result<(), StorageError>, ScheduleError>> {
self.queue.pop().map(|command| {
scheduler.schedule(|| match command {
StorageCommand::Put { key, value } => store.put(&key, &value),
StorageCommand::Delete { key } => store.delete(&key).map(|_| ()),
})
})
}
}