use std::marker::PhantomData;
use std::sync::Arc;
use bytes::Bytes;
use serde::de::DeserializeOwned;
use crate::queue::backend::ReceiverBackend;
use crate::queue::error::WorkQueueRecvError;
use crate::queue::options::NextOptions;
pub struct WorkQueueReceiver<T: DeserializeOwned> {
backend: Arc<dyn ReceiverBackend>,
_marker: PhantomData<fn() -> T>,
}
impl<T: DeserializeOwned> Clone for WorkQueueReceiver<T> {
fn clone(&self) -> Self {
Self {
backend: Arc::clone(&self.backend),
_marker: PhantomData,
}
}
}
impl<T: DeserializeOwned> WorkQueueReceiver<T> {
pub(crate) fn new(backend: Arc<dyn ReceiverBackend>) -> Self {
Self {
backend,
_marker: PhantomData,
}
}
pub async fn next(&self) -> Result<Option<T>, WorkQueueRecvError> {
match self.backend.recv().await? {
Some(bytes) => Ok(Some(deserialize(&bytes)?)),
None => Ok(None),
}
}
pub async fn next_with_options(
&self,
options: NextOptions,
) -> Result<Vec<T>, WorkQueueRecvError> {
let raw = self.backend.recv_batch(&options).await?;
raw.iter().map(|b| deserialize(b)).collect()
}
pub fn try_next(&self) -> Result<Option<T>, WorkQueueRecvError> {
match self.backend.try_recv()? {
Some(bytes) => Ok(Some(deserialize(&bytes)?)),
None => Ok(None),
}
}
}
fn deserialize<T: DeserializeOwned>(bytes: &Bytes) -> Result<T, WorkQueueRecvError> {
rmp_serde::from_slice(bytes).map_err(|e| WorkQueueRecvError::Deserialization(e.to_string()))
}