use crate::connection::ConnError;
use crate::connection::Connection;
use crate::frame::Frame;
use futures::stream::Stream;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::sync::mpsc;
#[derive(Debug, Clone, Default)]
pub struct SubscriptionOptions {
pub headers: Vec<(String, String)>,
}
pub struct Subscription {
id: String,
destination: String,
receiver: mpsc::Receiver<Frame>,
conn: Connection,
unsubscribed: bool,
}
impl Subscription {
pub(crate) fn new(
id: String,
destination: String,
receiver: mpsc::Receiver<Frame>,
conn: Connection,
) -> Self {
Self {
id,
destination,
receiver,
conn,
unsubscribed: false,
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn destination(&self) -> &str {
&self.destination
}
pub fn into_receiver(mut self) -> mpsc::Receiver<Frame> {
self.unsubscribed = true;
let (_dummy_tx, dummy_rx) = mpsc::channel(1);
std::mem::replace(&mut self.receiver, dummy_rx)
}
pub async fn ack(&self, message_id: &str) -> Result<(), ConnError> {
self.conn.ack(&self.id, message_id).await
}
pub async fn nack(&self, message_id: &str) -> Result<(), ConnError> {
self.conn.nack(&self.id, message_id).await
}
pub async fn unsubscribe(mut self) -> Result<(), ConnError> {
self.unsubscribed = true;
self.conn.unsubscribe(&self.id).await
}
}
impl Drop for Subscription {
fn drop(&mut self) {
if self.unsubscribed {
return;
}
self.conn.unsubscribe_best_effort(&self.id);
}
}
impl Stream for Subscription {
type Item = Frame;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.get_mut();
Pin::new(&mut this.receiver).poll_recv(cx)
}
}