use crate::AlgebraMessage;
use alux_sdk::{AlgebraCall, AlgebraSend};
use futures::stream::AbortHandle;
use std::fmt::{self, Debug, Formatter};
use tokio::sync::{mpsc, oneshot};
pub struct BoundedAlgebraSender<Operation, Reply> {
sender: mpsc::Sender<AlgebraMessage<Operation, Reply>>,
stop: AbortHandle,
}
impl<Operation, Reply> BoundedAlgebraSender<Operation, Reply> {
pub(crate) const fn from_sender(sender: mpsc::Sender<AlgebraMessage<Operation, Reply>>, stop: AbortHandle) -> Self {
Self { sender, stop }
}
pub async fn put(&self, message: AlgebraMessage<Operation, Reply>) -> Option<()> {
self.sender.send(message).await.ok()
}
#[must_use = "a feed whose reader is gone states nothing, and only the caller knows what that means"]
pub async fn send(&self, operation: Operation) -> Option<()> {
self.put(AlgebraMessage::unheard(operation)).await
}
pub fn stop(&self) {
self.stop.abort();
}
}
impl<Operation, Reply> Clone for BoundedAlgebraSender<Operation, Reply> {
fn clone(&self) -> Self {
Self { sender: self.sender.clone(), stop: self.stop.clone() }
}
}
impl<Operation, Reply> Debug for BoundedAlgebraSender<Operation, Reply> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
formatter.debug_struct("BoundedAlgebraSender").finish_non_exhaustive()
}
}
impl<Operation, Reply> AlgebraSend<Operation> for BoundedAlgebraSender<Operation, Reply>
where
Operation: Send,
Reply: Send,
{
async fn send(&self, operation: Operation) -> Option<()> {
self.put(AlgebraMessage::unheard(operation)).await
}
}
impl<Operation, Reply> AlgebraCall<Operation, Reply> for BoundedAlgebraSender<Operation, Reply>
where
Operation: Send,
Reply: Send,
{
async fn ask(&self, operation: Operation) -> Option<Reply> {
let (answering, answer) = oneshot::channel();
self.put(AlgebraMessage::new(operation, answering)).await;
answer.await.ok()
}
}