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