tether_agent/agent/
builder.rs1use std::sync::{mpsc, Arc, Mutex};
2
3use log::*;
4
5use crate::tether_compliant_topic::TetherOrCustomTopic;
6
7use super::TetherAgent;
8
9const DEFAULT_USERNAME: &str = "tether";
10const DEFAULT_PASSWORD: &str = "sp_ceB0ss!";
11
12#[derive(Clone)]
20pub struct TetherAgentBuilder {
21 role: String,
22 id: Option<String>,
23 protocol: Option<String>,
24 host: Option<String>,
25 port: Option<u16>,
26 username: Option<String>,
27 password: Option<String>,
28 base_path: Option<String>,
29 auto_connect: bool,
30 mqtt_client_id: Option<String>,
31}
32
33impl TetherAgentBuilder {
34 pub fn new(role: &str) -> Self {
37 TetherAgentBuilder {
38 role: String::from(role),
39 id: None,
40 protocol: None,
41 host: None,
42 port: None,
43 username: None,
44 password: None,
45 base_path: None,
46 auto_connect: true,
47 mqtt_client_id: None,
48 }
49 }
50
51 pub fn id(mut self, id: Option<&str>) -> Self {
54 self.id = id.map(|x| x.into());
55 self
56 }
57
58 pub fn protocol(mut self, protocol: Option<&str>) -> Self {
60 self.protocol = protocol.map(|x| x.into());
61 self
62 }
63
64 pub fn mqtt_client_id(mut self, client_id: Option<&str>) -> Self {
70 self.mqtt_client_id = client_id.map(|x| x.into());
71 self
72 }
73
74 pub fn host(mut self, host: Option<&str>) -> Self {
76 self.host = host.map(|x| x.into());
77 self
78 }
79
80 pub fn port(mut self, port: Option<u16>) -> Self {
81 self.port = port;
82 self
83 }
84
85 pub fn username(mut self, username: Option<&str>) -> Self {
87 self.username = username.map(|x| x.into());
88 self
89 }
90
91 pub fn password(mut self, password: Option<&str>) -> Self {
93 self.password = password.map(|x| x.into());
94 self
95 }
96
97 pub fn base_path(mut self, base_path: Option<&str>) -> Self {
99 self.base_path = base_path.map(|x| x.into());
100 self
101 }
102
103 pub fn auto_connect(mut self, should_auto_connect: bool) -> Self {
107 self.auto_connect = should_auto_connect;
108 self
109 }
110
111 pub fn build(self) -> anyhow::Result<TetherAgent> {
118 let protocol = self.protocol.clone().unwrap_or("mqtt".into());
119 let host = self.host.clone().unwrap_or("localhost".into());
120 let port = self.port.unwrap_or(1883);
121 let username = self.username.unwrap_or(DEFAULT_USERNAME.into());
122 let password = self.password.unwrap_or(DEFAULT_PASSWORD.into());
123 let base_path = self.base_path.unwrap_or("/".into());
124
125 debug!(
126 "final build uses options protocol = {}, host = {}, port = {}",
127 protocol, host, port
128 );
129
130 let (message_sender, message_receiver) = mpsc::channel::<(TetherOrCustomTopic, Vec<u8>)>();
131
132 let mut agent = TetherAgent {
133 role: self.role.clone(),
134 id: self.id,
135 host,
136 port,
137 username,
138 password,
139 protocol,
140 base_path,
141 client: None,
142 message_sender,
143 message_receiver,
144 mqtt_client_id: self.mqtt_client_id,
145 is_connected: Arc::new(Mutex::new(false)),
146 auto_connect_enabled: self.auto_connect,
147 };
148
149 if self.auto_connect {
150 match agent.connect() {
151 Ok(()) => Ok(agent),
152 Err(e) => Err(e),
153 }
154 } else {
155 warn!("Auto-connect disabled; you must call .connect explicitly");
156 Ok(agent)
157 }
158 }
159}