tether_agent/channels/definitions/
mod.rs1use super::tether_compliant_topic::TetherOrCustomTopic;
2
3pub mod receiver_def_builder;
4pub mod sender_def_builder;
5
6pub use receiver_def_builder::ChannelReceiverDefBuilder;
7use rumqttc::QoS;
8pub use sender_def_builder::ChannelSenderDefBuilder;
9use serde::{Deserialize, Serialize};
10
11pub trait ChannelDefBuilder {
15 fn new(name: &str) -> Self;
16 fn qos(self, qos: Option<QoS>) -> Self;
17 fn role(self, role: Option<&str>) -> Self;
18 fn id(self, id: Option<&str>) -> Self;
19 fn override_name(self, override_channel_name: Option<&str>) -> Self;
20 fn override_topic(self, override_topic: Option<&str>) -> Self;
21}
22
23pub trait ChannelDef<'a> {
29 fn name(&'a self) -> &'a str;
30 fn generated_topic(&'a self) -> &'a str;
32 fn topic(&'a self) -> &'a TetherOrCustomTopic;
34 fn qos(&'a self) -> QoS;
35}
36
37pub fn number_to_qos(number: u8) -> QoS {
38 match number {
39 0 => QoS::AtMostOnce,
40 1 => QoS::AtLeastOnce,
41 2 => QoS::ExactlyOnce,
42 _ => QoS::AtMostOnce,
43 }
44}
45
46pub fn qos_to_number(qos: QoS) -> u8 {
47 match qos {
48 QoS::AtMostOnce => 0,
49 QoS::AtLeastOnce => 1,
50 QoS::ExactlyOnce => 2,
51 }
52}
53
54#[derive(Serialize, Deserialize)]
55#[serde(remote = "QoS")]
56#[allow(renamed_and_removed_lints)]
57#[allow(enum_variant_names)]
58enum QosDef {
59 AtMostOnce,
60 AtLeastOnce,
61 ExactlyOnce,
62}
63
64#[derive(Clone, Serialize, Deserialize)]
65pub struct ChannelSenderDef {
66 pub name: String,
67 pub generated_topic: String,
68 pub topic: TetherOrCustomTopic,
69 #[serde(with = "QosDef")]
70 pub qos: QoS,
71 pub retain: bool,
72}
73
74impl ChannelSenderDef {
117 pub fn retain(&self) -> bool {
118 self.retain
119 }
120}
121
122#[derive(Clone, Deserialize, Serialize)]
123pub struct ChannelReceiverDef {
124 pub name: String,
125 pub generated_topic: String,
126 pub topic: TetherOrCustomTopic,
127 #[serde(with = "QosDef")]
128 pub qos: QoS,
129}
130
131impl<'a> ChannelDef<'a> for ChannelSenderDef {
132 fn name(&'a self) -> &'a str {
133 &self.name
134 }
135
136 fn generated_topic(&'a self) -> &'a str {
137 &self.generated_topic
138 }
139
140 fn topic(&'a self) -> &'a TetherOrCustomTopic {
141 &self.topic
142 }
143
144 fn qos(&'a self) -> QoS {
145 self.qos
146 }
147}
148
149impl<'a> ChannelDef<'a> for ChannelReceiverDef {
150 fn name(&'a self) -> &'a str {
151 &self.name
152 }
153
154 fn generated_topic(&'a self) -> &'a str {
155 &self.generated_topic
156 }
157
158 fn topic(&'a self) -> &'a TetherOrCustomTopic {
159 &self.topic
160 }
161
162 fn qos(&'a self) -> QoS {
163 self.qos
164 }
165}
166
167#[cfg(test)]
168mod tests {
169
170 fn verbose_logging() {
171 use env_logger::{Builder, Env};
172 let mut logger_builder = Builder::from_env(Env::default().default_filter_or("debug"));
173 logger_builder.init();
174 }
175
176 use crate::{
177 builder::TetherAgentBuilder, ChannelDef, ChannelDefBuilder, ChannelReceiverDefBuilder,
178 ChannelSenderDefBuilder,
179 };
180
181 #[test]
182 fn default_receiver_channel() {
183 let tether_agent = TetherAgentBuilder::new("tester")
185 .auto_connect(false)
186 .build()
187 .expect("sorry, these tests require working localhost Broker");
188 let receiver = ChannelReceiverDefBuilder::new("one").build(&tether_agent);
189 assert_eq!(&receiver.name, "one");
190 assert_eq!(&receiver.generated_topic, "+/one/#");
191 }
192
193 #[test]
194 fn default_channel_receiver_with_agent_custom_id() {
199 let tether_agent = TetherAgentBuilder::new("tester")
201 .auto_connect(false)
202 .id(Some("verySpecialGroup"))
203 .build()
204 .expect("sorry, these tests require working localhost Broker");
205 let receiver = tether_agent.create_receiver::<u8>("one").unwrap();
206 assert_eq!(receiver.definition().name(), "one");
207 assert_eq!(
208 receiver.definition().generated_topic(),
209 "+/one/verySpecialGroup"
210 );
211 }
212
213 #[test]
214 fn default_channel_sender() {
215 let tether_agent = TetherAgentBuilder::new("tester")
216 .auto_connect(false)
217 .build()
218 .expect("sorry, these tests require working localhost Broker");
219 let channel = tether_agent.create_sender::<u8>("two");
220 assert_eq!(channel.definition().name(), "two");
221 assert_eq!(channel.definition().generated_topic(), "tester/two");
222 }
223
224 #[test]
225 fn sender_channel_default_but_agent_id_custom() {
229 let tether_agent = TetherAgentBuilder::new("tester")
230 .auto_connect(false)
231 .id(Some("specialCustomGrouping"))
232 .build()
233 .expect("sorry, these tests require working localhost Broker");
234 let channel = tether_agent.create_sender::<u8>("somethingStandard");
235 assert_eq!(channel.definition().name(), "somethingStandard");
236 assert_eq!(
237 channel.definition().generated_topic(),
238 "tester/somethingStandard/specialCustomGrouping"
239 );
240 }
241
242 #[test]
243 fn receiver_id_andor_role() {
244 let tether_agent = TetherAgentBuilder::new("tester")
245 .auto_connect(false)
246 .build()
247 .expect("sorry, these tests require working localhost Broker");
248
249 let receive_role_only = ChannelReceiverDefBuilder::new("theChannel")
250 .role(Some("specificRole"))
251 .build(&tether_agent);
252 assert_eq!(receive_role_only.name(), "theChannel");
253 assert_eq!(
254 receive_role_only.generated_topic(),
255 "specificRole/theChannel/#"
256 );
257
258 let receiver_id_only = ChannelReceiverDefBuilder::new("theChannel")
259 .id(Some("specificID"))
260 .build(&tether_agent);
261 assert_eq!(receiver_id_only.name(), "theChannel");
262 assert_eq!(
263 receiver_id_only.generated_topic(),
264 "+/theChannel/specificID"
265 );
266
267 let receiver_both_custom = ChannelReceiverDefBuilder::new("theChannel")
268 .id(Some("specificID"))
269 .role(Some("specificRole"))
270 .build(&tether_agent);
271 assert_eq!(receiver_both_custom.name(), "theChannel");
272 assert_eq!(
273 receiver_both_custom.generated_topic(),
274 "specificRole/theChannel/specificID"
275 );
276 }
277
278 #[test]
279 fn receiver_specific_id_andor_role_with_channel_name() {
284 let tether_agent = TetherAgentBuilder::new("tester")
285 .auto_connect(false)
286 .build()
287 .expect("sorry, these tests require working localhost Broker");
288
289 let receiver_role_only = ChannelReceiverDefBuilder::new("theChannel")
290 .role(Some("specificRole"))
291 .build(&tether_agent);
292 assert_eq!(receiver_role_only.name(), "theChannel");
293 assert_eq!(
294 receiver_role_only.generated_topic(),
295 "specificRole/theChannel/#"
296 );
297
298 let receiver_id_only = ChannelReceiverDefBuilder::new("theChannel")
299 .id(Some("specificID"))
300 .build(&tether_agent);
301 assert_eq!(receiver_id_only.name(), "theChannel");
302 assert_eq!(
303 receiver_id_only.generated_topic(),
304 "+/theChannel/specificID"
305 );
306
307 let receiver_both = ChannelReceiverDefBuilder::new("theChannel")
308 .id(Some("specificID"))
309 .role(Some("specificRole"))
310 .build(&tether_agent);
311 assert_eq!(receiver_both.name(), "theChannel");
312 assert_eq!(
313 receiver_both.generated_topic(),
314 "specificRole/theChannel/specificID"
315 );
316 }
317
318 #[test]
319 fn receiver_specific_id_andor_role_no_channel_name() {
324 verbose_logging();
325 let tether_agent = TetherAgentBuilder::new("tester")
326 .auto_connect(false)
327 .build()
328 .expect("sorry, these tests require working localhost Broker");
329
330 let receiver_role_only = ChannelReceiverDefBuilder::new("theOriginalChannel")
331 .override_name(Some("+"))
332 .role(Some("specificRole"))
333 .build(&tether_agent);
334 assert_eq!(receiver_role_only.name(), "+");
335 assert_eq!(receiver_role_only.generated_topic(), "specificRole/+/#");
336
337 let receiver_id_only = ChannelReceiverDefBuilder::new("+")
338 .any_channel() .id(Some("specificID"))
341 .build(&tether_agent);
342 assert_eq!(receiver_id_only.name(), "+");
343 assert_eq!(receiver_id_only.generated_topic(), "+/+/specificID");
344
345 let receiver_both = ChannelReceiverDefBuilder::new("+")
346 .id(Some("specificID"))
347 .role(Some("specificRole"))
348 .build(&tether_agent);
349 assert_eq!(receiver_both.name(), "+");
350 assert_eq!(receiver_both.generated_topic(), "specificRole/+/specificID");
351 }
352
353 #[test]
354 fn any_name_but_specify_role() {
356 let tether_agent = TetherAgentBuilder::new("tester")
357 .auto_connect(false)
358 .build()
359 .expect("sorry, these tests require working localhost Broker");
360
361 let receiver_any_channel = ChannelReceiverDefBuilder::new("aTest")
362 .any_channel()
363 .build(&tether_agent);
364
365 assert_eq!(receiver_any_channel.name(), "+");
366 assert_eq!(receiver_any_channel.generated_topic(), "+/+/#");
367
368 let receiver_specify_role = ChannelReceiverDefBuilder::new("aTest")
369 .any_channel()
370 .role(Some("brain"))
371 .build(&tether_agent);
372
373 assert_eq!(receiver_specify_role.name(), "+");
374 assert_eq!(receiver_specify_role.generated_topic(), "brain/+/#");
375 }
376
377 #[test]
378 fn sender_custom() {
379 let tether_agent = TetherAgentBuilder::new("tester")
380 .auto_connect(false)
381 .build()
382 .expect("sorry, these tests require working localhost Broker");
383
384 let sender_custom_role = ChannelSenderDefBuilder::new("theChannelSender")
385 .role(Some("customRole"))
386 .build(&tether_agent);
387 assert_eq!(sender_custom_role.name(), "theChannelSender");
388 assert_eq!(
389 sender_custom_role.generated_topic(),
390 "customRole/theChannelSender"
391 );
392
393 let sender_custom_id = ChannelSenderDefBuilder::new("theChannelSender")
394 .id(Some("customID"))
395 .build(&tether_agent);
396 assert_eq!(sender_custom_id.name(), "theChannelSender");
397 assert_eq!(
398 sender_custom_id.generated_topic(),
399 "tester/theChannelSender/customID"
400 );
401
402 let sender_custom_both = ChannelSenderDefBuilder::new("theChannelSender")
403 .role(Some("customRole"))
404 .id(Some("customID"))
405 .build(&tether_agent);
406 assert_eq!(sender_custom_both.name(), "theChannelSender");
407 assert_eq!(
408 sender_custom_both.generated_topic(),
409 "customRole/theChannelSender/customID"
410 );
411 }
412
413 #[test]
414 fn receiver_manual_topics() {
415 let tether_agent = TetherAgentBuilder::new("tester")
416 .auto_connect(false)
417 .build()
418 .expect("sorry, these tests require working localhost Broker");
419
420 let receiver_all = ChannelReceiverDefBuilder::new("everything")
421 .override_topic(Some("#"))
422 .build(&tether_agent);
423 assert_eq!(receiver_all.name(), "everything");
424 assert_eq!(receiver_all.generated_topic(), "#");
425
426 let receiver_nontether = ChannelReceiverDefBuilder::new("weird")
427 .override_topic(Some("foo/bar/baz/one/two/three"))
428 .build(&tether_agent);
429 assert_eq!(receiver_nontether.name(), "weird");
430 assert_eq!(
431 receiver_nontether.generated_topic(),
432 "foo/bar/baz/one/two/three"
433 );
434 }
435}