1use core::fmt::{self, Debug, Display, Formatter};
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6#[cfg(feature = "use_serde")]
7use serde::{Deserialize, Serialize};
8
9pub trait ErrorType {
10 type Error: Debug;
11}
12
13impl<E> ErrorType for &E
14where
15 E: ErrorType,
16{
17 type Error = E::Error;
18}
19
20impl<E> ErrorType for &mut E
21where
22 E: ErrorType,
23{
24 type Error = E::Error;
25}
26
27#[repr(u8)]
29#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
30#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
32pub enum QoS {
33 AtMostOnce = 0,
34 AtLeastOnce = 1,
35 ExactlyOnce = 2,
36}
37
38pub type MessageId = u32;
39
40pub trait Event: ErrorType {
41 fn payload(&self) -> EventPayload<'_, Self::Error>;
42}
43
44impl<E> Event for &E
45where
46 E: Event,
47{
48 fn payload(&self) -> EventPayload<'_, Self::Error> {
49 (*self).payload()
50 }
51}
52
53impl<E> Event for &mut E
54where
55 E: Event,
56{
57 fn payload(&self) -> EventPayload<'_, Self::Error> {
58 (**self).payload()
59 }
60}
61
62#[derive(Clone, PartialEq, Eq, Debug)]
63#[cfg_attr(feature = "defmt", derive(defmt::Format))]
64pub enum EventPayload<'a, E> {
65 BeforeConnect,
66 Connected(bool),
67 Disconnected,
68 Subscribed(MessageId),
69 Unsubscribed(MessageId),
70 Published(MessageId),
71 Received {
72 id: MessageId,
73 topic: Option<&'a str>,
74 data: &'a [u8],
75 details: Details,
76 },
77 Deleted(MessageId),
78 Error(&'a E),
79}
80
81impl<E> Display for EventPayload<'_, E>
82where
83 E: Debug,
84{
85 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
86 match self {
87 Self::BeforeConnect => write!(f, "BeforeConnect"),
88 Self::Connected(session_present) => write!(f, "Connected(session: {session_present})"),
89 Self::Disconnected => write!(f, "Disconnected"),
90 Self::Subscribed(message_id) => write!(f, "Subscribed({message_id})"),
91 Self::Unsubscribed(message_id) => write!(f, "Unsubscribed({message_id})"),
92 Self::Published(message_id) => write!(f, "Published({message_id})"),
93 Self::Received {
94 id,
95 topic,
96 data,
97 details,
98 } => write!(
99 f,
100 "Received {{ id: {id}, topic: {topic:?}, data: {:?}, details: {details:?} }}",
101 core::str::from_utf8(data),
102 ),
103 Self::Deleted(message_id) => write!(f, "Deleted({message_id})"),
104 Self::Error(error) => write!(f, "Error({error:?})"),
105 }
106 }
107}
108
109#[derive(Debug, Copy, Clone, PartialEq, Eq)]
110#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
112pub enum Details {
113 Complete,
114 InitialChunk(InitialChunkData),
115 SubsequentChunk(SubsequentChunkData),
116}
117
118#[derive(Debug, Copy, Clone, PartialEq, Eq)]
119#[cfg_attr(feature = "defmt", derive(defmt::Format))]
120#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
121pub struct InitialChunkData {
122 pub total_data_size: usize,
123}
124
125#[derive(Debug, Copy, Clone, PartialEq, Eq)]
126#[cfg_attr(feature = "defmt", derive(defmt::Format))]
127#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
128pub struct SubsequentChunkData {
129 pub current_data_offset: usize,
130 pub total_data_size: usize,
131}
132
133pub trait Client: ErrorType {
134 fn subscribe<'a>(&'a mut self, topic: &'a str, qos: QoS) -> Result<MessageId, Self::Error>;
135
136 fn unsubscribe<'a>(&'a mut self, topic: &'a str) -> Result<MessageId, Self::Error>;
137}
138
139impl<C> Client for &mut C
140where
141 C: Client,
142{
143 fn subscribe<'a>(&'a mut self, topic: &'a str, qos: QoS) -> Result<MessageId, Self::Error> {
144 (*self).subscribe(topic, qos)
145 }
146
147 fn unsubscribe<'a>(&'a mut self, topic: &'a str) -> Result<MessageId, Self::Error> {
148 (*self).unsubscribe(topic)
149 }
150}
151
152pub trait Publish: ErrorType {
153 fn publish<'a>(
154 &'a mut self,
155 topic: &'a str,
156 qos: QoS,
157 retain: bool,
158 payload: &'a [u8],
159 ) -> Result<MessageId, Self::Error>;
160}
161
162impl<P> Publish for &mut P
163where
164 P: Publish,
165{
166 fn publish<'a>(
167 &'a mut self,
168 topic: &'a str,
169 qos: QoS,
170 retain: bool,
171 payload: &'a [u8],
172 ) -> Result<MessageId, Self::Error> {
173 (*self).publish(topic, qos, retain, payload)
174 }
175}
176
177pub trait Enqueue: ErrorType {
178 fn enqueue<'a>(
179 &'a mut self,
180 topic: &'a str,
181 qos: QoS,
182 retain: bool,
183 payload: &'a [u8],
184 ) -> Result<MessageId, Self::Error>;
185}
186
187impl<E> Enqueue for &mut E
188where
189 E: Enqueue,
190{
191 fn enqueue<'a>(
192 &'a mut self,
193 topic: &'a str,
194 qos: QoS,
195 retain: bool,
196 payload: &'a [u8],
197 ) -> Result<MessageId, Self::Error> {
198 (*self).enqueue(topic, qos, retain, payload)
199 }
200}
201
202pub trait Connection: ErrorType {
203 type Event<'a>: Event
204 where
205 Self: 'a;
206
207 fn next(&mut self) -> Result<Self::Event<'_>, Self::Error>;
208}
209
210impl<C> Connection for &mut C
211where
212 C: Connection,
213{
214 type Event<'a>
215 = C::Event<'a>
216 where
217 Self: 'a;
218
219 fn next(&mut self) -> Result<Self::Event<'_>, Self::Error> {
220 (*self).next()
221 }
222}
223
224pub mod asynch {
225 pub use super::{Details, ErrorType, Event, EventPayload, MessageId, QoS};
226
227 pub trait Client: ErrorType {
228 async fn subscribe(&mut self, topic: &str, qos: QoS) -> Result<MessageId, Self::Error>;
229
230 async fn unsubscribe(&mut self, topic: &str) -> Result<MessageId, Self::Error>;
231 }
232
233 impl<C> Client for &mut C
234 where
235 C: Client,
236 {
237 async fn subscribe(&mut self, topic: &str, qos: QoS) -> Result<MessageId, Self::Error> {
238 (*self).subscribe(topic, qos).await
239 }
240
241 async fn unsubscribe(&mut self, topic: &str) -> Result<MessageId, Self::Error> {
242 (*self).unsubscribe(topic).await
243 }
244 }
245
246 pub trait Publish: ErrorType {
247 async fn publish(
248 &mut self,
249 topic: &str,
250 qos: QoS,
251 retain: bool,
252 payload: &[u8],
253 ) -> Result<MessageId, Self::Error>;
254 }
255
256 impl<P> Publish for &mut P
257 where
258 P: Publish,
259 {
260 async fn publish(
261 &mut self,
262 topic: &str,
263 qos: QoS,
264 retain: bool,
265 payload: &[u8],
266 ) -> Result<MessageId, Self::Error> {
267 (*self).publish(topic, qos, retain, payload).await
268 }
269 }
270
271 pub trait Connection: ErrorType {
272 type Event<'a>: Event
273 where
274 Self: 'a;
275
276 async fn next(&mut self) -> Result<Self::Event<'_>, Self::Error>;
277 }
278
279 impl<C> Connection for &mut C
280 where
281 C: Connection,
282 {
283 type Event<'a>
284 = C::Event<'a>
285 where
286 Self: 'a;
287
288 async fn next(&mut self) -> Result<Self::Event<'_>, Self::Error> {
289 (*self).next().await
290 }
291 }
292}