1use crate::constants::STATE;
2
3use super::constants::{DBIRTH, DCMD, DDATA, DDEATH, NBIRTH, NCMD, NDATA, NDEATH, SPBV01};
4
5#[derive(Clone, Debug, PartialEq)]
6pub enum DeviceMessage {
7 DBirth,
8 DDeath,
9 DData,
10 DCmd,
11}
12
13impl DeviceMessage {
14 fn as_str(&self) -> &str {
15 match self {
16 DeviceMessage::DBirth => DBIRTH,
17 DeviceMessage::DDeath => DDEATH,
18 DeviceMessage::DData => DDATA,
19 DeviceMessage::DCmd => DCMD,
20 }
21 }
22}
23
24#[derive(Clone, Debug, PartialEq)]
25pub enum NodeMessage {
26 NBirth,
27 NDeath,
28 NData,
29 NCmd,
30}
31
32impl NodeMessage {
33 fn as_str(&self) -> &str {
34 match self {
35 NodeMessage::NBirth => NBIRTH,
36 NodeMessage::NDeath => NDEATH,
37 NodeMessage::NData => NDATA,
38 NodeMessage::NCmd => NCMD,
39 }
40 }
41}
42
43#[derive(Clone, Debug, PartialEq)]
44pub struct NodeTopic {
45 pub topic: String,
46 pub message_type: NodeMessage,
47}
48
49impl NodeTopic {
50 pub fn new(group_id: &str, message_type: NodeMessage, node_id: &str) -> Self {
51 Self {
52 topic: node_topic(group_id, &message_type, node_id),
53 message_type,
54 }
55 }
56
57 pub fn get_publish_quality_retain(&self) -> (QoS, bool) {
58 match self.message_type {
59 NodeMessage::NBirth => (QoS::AtMostOnce, false),
60 NodeMessage::NData => (QoS::AtMostOnce, false),
61 NodeMessage::NCmd => (QoS::AtMostOnce, false),
62 NodeMessage::NDeath => (QoS::AtLeastOnce, false),
63 }
64 }
65}
66
67#[derive(Clone, Debug, PartialEq)]
68pub struct DeviceTopic {
69 pub topic: String,
70 pub message_type: DeviceMessage,
71}
72
73impl DeviceTopic {
74 pub fn new(
75 group_id: &str,
76 message_type: DeviceMessage,
77 node_id: &str,
78 device_id: &str,
79 ) -> Self {
80 Self {
81 topic: device_topic(group_id, &message_type, node_id, device_id),
82 message_type,
83 }
84 }
85
86 pub fn get_publish_quality_retain(&self) -> (QoS, bool) {
87 match self.message_type {
88 DeviceMessage::DBirth => (QoS::AtLeastOnce, false),
89 DeviceMessage::DData => (QoS::AtMostOnce, false),
90 DeviceMessage::DCmd => (QoS::AtMostOnce, false),
91 DeviceMessage::DDeath => (QoS::AtLeastOnce, false),
92 }
93 }
94}
95
96#[derive(Clone, Debug, PartialEq)]
97pub struct StateTopic {
98 pub topic: String,
99}
100
101impl Default for StateTopic {
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107impl StateTopic {
108 pub fn new() -> Self {
109 Self {
110 topic: state_sub_topic(),
111 }
112 }
113
114 pub fn new_host(host_id: &str) -> Self {
115 Self {
116 topic: state_host_topic(host_id),
117 }
118 }
119}
120
121#[derive(Clone, Debug, PartialEq)]
122pub enum Topic {
123 NodeTopic(NodeTopic),
124 DeviceTopic(DeviceTopic),
125 State(StateTopic),
126 Node { group_id: String, node_id: String },
127 Group { id: String },
128 FullNamespace,
129}
130
131impl From<Topic> for String {
132 fn from(val: Topic) -> Self {
133 match val {
134 Topic::NodeTopic(node_topic) => node_topic.topic,
135 Topic::DeviceTopic(device_topic) => device_topic.topic,
136 Topic::State(state_topic) => state_topic.topic,
137 Topic::Node { group_id, node_id } => format!("{SPBV01}/{group_id}/+/{node_id}/#"),
138 Topic::Group { id } => format!("{SPBV01}/{id}/+/#"),
139 Topic::FullNamespace => format!("{SPBV01}/#"),
140 }
141 }
142}
143
144#[derive(Clone, Debug, PartialEq)]
145pub enum QoS {
146 AtMostOnce,
147 AtLeastOnce,
148}
149
150#[derive(Clone, Debug, PartialEq)]
151pub struct TopicFilter {
152 pub topic: Topic,
153 pub qos: QoS,
154}
155
156impl TopicFilter {
157 pub fn new(topic: Topic) -> Self {
158 Self::new_with_qos(topic, QoS::AtMostOnce)
159 }
160
161 pub fn new_with_qos(topic: Topic, qos: QoS) -> Self {
162 Self { topic, qos }
163 }
164}
165
166pub fn node_topic_raw(group_id: &str, message_type: &str, node_id: &str) -> String {
167 format!("{SPBV01}/{group_id}/{message_type}/{node_id}")
168}
169
170pub fn node_topic(group_id: &str, message_type: &NodeMessage, node_id: &str) -> String {
171 node_topic_raw(group_id, message_type.as_str(), node_id)
172}
173
174pub fn device_topic(
175 group_id: &str,
176 message_type: &DeviceMessage,
177 node_id: &str,
178 device_id: &str,
179) -> String {
180 let message_type = message_type.as_str();
181 format!("{SPBV01}/{group_id}/{message_type}/{node_id}/{device_id}")
182}
183
184pub fn state_host_topic(host_id: &str) -> String {
185 format!("{SPBV01}/{STATE}/{host_id}")
186}
187
188pub fn state_sub_topic() -> String {
189 state_host_topic("#")
190}