mod builder;
mod config;
mod message;
mod mqtt;
use std::sync::Arc;
use anyhow::Result;
use fluent_uri::Uri;
use parking_lot::RwLock;
use self::mqtt::PublishStore;
pub use mqttbytes::QoS;
pub use self::{
builder::{MqttClientBuilder, MqttClientBuilderError},
config::{OnConnectedCallback, OnMessageCallback},
message::{Message, MessageBuilder},
mqtt::MqttWorker,
};
use crate::client::config::{MqttClientConfig, OnMessageOwnedCallback};
#[derive(Clone)]
pub struct MqttClient {
config: Arc<RwLock<MqttClientConfig>>,
publish_store: Arc<PublishStore>,
}
impl MqttClient {
fn new(
mqtt_broker: Uri<String>,
config: MqttClientConfig,
on_message_owned: Option<Box<OnMessageOwnedCallback>>,
) -> (Self, MqttWorker) {
let config = Arc::new(RwLock::new(config));
let (worker, publish_store) =
MqttWorker::new(mqtt_broker, config.clone(), on_message_owned);
let client = Self {
config,
publish_store,
};
(client, worker)
}
pub fn set_on_message_callback<F>(&self, callback: F)
where
F: FnMut(&Message) + Send + Sync + 'static,
{
self.config.write().on_message_callback = Some(Box::new(callback));
}
pub fn set_on_connected_callback<F>(&self, callback: F)
where
F: Fn() + Send + Sync + 'static,
{
self.config.write().on_connected_callback = Some(Box::new(callback));
}
pub fn publish_raw(&self, message: Message) -> Result<()> {
self.publish_store.insert_to_send(message);
Ok(())
}
pub fn tx_pending(&self) -> usize {
self.publish_store.tx_pending()
}
#[cfg(feature = "json")]
pub fn publish_json<S, T>(
&self,
topic: S,
payload: &T,
retained: bool,
qos: QoS,
expiry_interval: Option<std::time::Duration>,
) -> Result<()>
where
S: Into<String>,
T: ?Sized + serde::Serialize,
{
let json = serde_json::to_string(payload)?;
let message = MessageBuilder::new()
.retained(retained)
.qos(qos)
.topic(topic)
.message_expiry_interval(expiry_interval)
.utf8(true)
.payload(json)
.finalize();
self.publish_raw(message)
}
}