srad_types/
topic.rs

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}