use std::sync::{mpsc, Arc, Mutex};
use log::*;
use crate::tether_compliant_topic::TetherOrCustomTopic;
use super::TetherAgent;
const DEFAULT_USERNAME: &str = "tether";
const DEFAULT_PASSWORD: &str = "sp_ceB0ss!";
#[derive(Clone)]
pub struct TetherAgentBuilder {
role: String,
id: Option<String>,
protocol: Option<String>,
host: Option<String>,
port: Option<u16>,
username: Option<String>,
password: Option<String>,
base_path: Option<String>,
auto_connect: bool,
mqtt_client_id: Option<String>,
}
impl TetherAgentBuilder {
pub fn new(role: &str) -> Self {
TetherAgentBuilder {
role: String::from(role),
id: None,
protocol: None,
host: None,
port: None,
username: None,
password: None,
base_path: None,
auto_connect: true,
mqtt_client_id: None,
}
}
pub fn id(mut self, id: Option<&str>) -> Self {
self.id = id.map(|x| x.into());
self
}
pub fn protocol(mut self, protocol: Option<&str>) -> Self {
self.protocol = protocol.map(|x| x.into());
self
}
pub fn mqtt_client_id(mut self, client_id: Option<&str>) -> Self {
self.mqtt_client_id = client_id.map(|x| x.into());
self
}
pub fn host(mut self, host: Option<&str>) -> Self {
self.host = host.map(|x| x.into());
self
}
pub fn port(mut self, port: Option<u16>) -> Self {
self.port = port;
self
}
pub fn username(mut self, username: Option<&str>) -> Self {
self.username = username.map(|x| x.into());
self
}
pub fn password(mut self, password: Option<&str>) -> Self {
self.password = password.map(|x| x.into());
self
}
pub fn base_path(mut self, base_path: Option<&str>) -> Self {
self.base_path = base_path.map(|x| x.into());
self
}
pub fn auto_connect(mut self, should_auto_connect: bool) -> Self {
self.auto_connect = should_auto_connect;
self
}
pub fn build(self) -> anyhow::Result<TetherAgent> {
let protocol = self.protocol.clone().unwrap_or("mqtt".into());
let host = self.host.clone().unwrap_or("localhost".into());
let port = self.port.unwrap_or(1883);
let username = self.username.unwrap_or(DEFAULT_USERNAME.into());
let password = self.password.unwrap_or(DEFAULT_PASSWORD.into());
let base_path = self.base_path.unwrap_or("/".into());
debug!(
"final build uses options protocol = {}, host = {}, port = {}",
protocol, host, port
);
let (message_sender, message_receiver) = mpsc::channel::<(TetherOrCustomTopic, Vec<u8>)>();
let mut agent = TetherAgent {
role: self.role.clone(),
id: self.id,
host,
port,
username,
password,
protocol,
base_path,
client: None,
message_sender,
message_receiver,
mqtt_client_id: self.mqtt_client_id,
is_connected: Arc::new(Mutex::new(false)),
auto_connect_enabled: self.auto_connect,
};
if self.auto_connect {
match agent.connect() {
Ok(()) => Ok(agent),
Err(e) => Err(e),
}
} else {
warn!("Auto-connect disabled; you must call .connect explicitly");
Ok(agent)
}
}
}