mqttrust_core/
client.rs

1use bbqueue::framed::FrameProducer;
2use core::cell::RefCell;
3use core::ops::DerefMut;
4use mqttrust::{
5    encoding::v4::{encoder::encode_slice, Packet},
6    Mqtt, MqttError,
7};
8/// MQTT Client
9///
10/// This client is meerly a convenience wrapper around a
11/// `heapless::spsc::Producer`, making it easier to send certain MQTT packet
12/// types, and maintaining a common reference to a client id. Also it implements
13/// the [`Mqtt`] trait.
14///
15/// **Lifetimes**:
16/// - 'a: The lifetime of the queue exhanging packets between the client and the
17///   event loop. This must have the same lifetime as the corresponding
18///   Consumer. Usually 'static.
19/// - 'b: The lifetime of client id str
20///
21/// **Generics**:
22/// - L: The length of the queue, exhanging packets between the client and the
23///   event loop. Length in number of request packets
24pub struct Client<'a, 'b, const L: usize> {
25    client_id: &'b str,
26    producer: RefCell<FrameProducer<'a, L>>,
27}
28
29impl<'a, 'b, const L: usize> Client<'a, 'b, L> {
30    pub fn new(producer: FrameProducer<'a, L>, client_id: &'b str) -> Self {
31        Self {
32            client_id,
33            producer: RefCell::new(producer),
34        }
35    }
36}
37
38impl<'a, 'b, const L: usize> Mqtt for Client<'a, 'b, L> {
39    fn client_id(&self) -> &str {
40        &self.client_id
41    }
42
43    fn send(&self, packet: Packet<'_>) -> Result<(), MqttError> {
44        let mut prod = self
45            .producer
46            .try_borrow_mut()
47            .map_err(|_| MqttError::Borrow)?;
48
49        let max_size = packet.len();
50        let mut grant = prod.grant(max_size).map_err(|_| MqttError::Full)?;
51
52        let len = encode_slice(&packet, grant.deref_mut()).map_err(|_| MqttError::Full)?;
53
54        grant.commit(len);
55
56        Ok(())
57    }
58}