use std::sync::Arc;
use futures::Stream;
use rumqttc::v5::AsyncClient;
use ruststream::Subscriber;
use tokio::sync::mpsc;
use crate::conn::Shared;
use crate::error::MqttError;
use crate::message::MqttMessage;
pub struct MqttSubscriber {
filter: String,
id: u64,
shared: Arc<Shared>,
client: AsyncClient,
rx: mpsc::UnboundedReceiver<Result<MqttMessage, MqttError>>,
}
impl std::fmt::Debug for MqttSubscriber {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MqttSubscriber")
.field("filter", &self.filter)
.finish_non_exhaustive()
}
}
impl MqttSubscriber {
pub(crate) fn new(
filter: String,
id: u64,
shared: Arc<Shared>,
client: AsyncClient,
rx: mpsc::UnboundedReceiver<Result<MqttMessage, MqttError>>,
) -> Self {
Self {
filter,
id,
shared,
client,
rx,
}
}
#[must_use]
pub fn filter(&self) -> &str {
&self.filter
}
}
impl Drop for MqttSubscriber {
fn drop(&mut self) {
if let Some(wire_filter) = self.shared.remove(self.id) {
let _ = self.client.try_unsubscribe(wire_filter);
}
}
}
impl Subscriber for MqttSubscriber {
type Message = MqttMessage;
type Error = MqttError;
fn stream(&mut self) -> impl Stream<Item = Result<MqttMessage, MqttError>> + Send + '_ {
futures::stream::poll_fn(move |cx| self.rx.poll_recv(cx))
}
}