Skip to main content

rust_mqtt/types/
pid.rs

1use core::num::NonZero;
2
3use crate::{
4    eio::{Read, Write},
5    io::{
6        err::{ReadError, WriteError},
7        read::Readable,
8        write::{Writable, wlen},
9    },
10};
11
12/// A simple wrapper around [`NonZero`]<[`u16`]>.
13#[derive(Clone, Copy, PartialEq, Eq)]
14pub struct PacketIdentifier(NonZero<u16>);
15
16impl PacketIdentifier {
17    pub(crate) const ONE: Self = Self::new(NonZero::new(1).unwrap());
18
19    pub(crate) const fn new(value: NonZero<u16>) -> Self {
20        Self(value)
21    }
22
23    pub(crate) fn next(self) -> Self {
24        NonZero::new(self.0.get().wrapping_add(1)).map_or(Self::ONE, Self)
25    }
26
27    /// Returns the underlying value.
28    #[must_use]
29    pub const fn get(self) -> NonZero<u16> {
30        self.0
31    }
32
33    pub(crate) const fn get_u16(self) -> u16 {
34        self.get().get()
35    }
36}
37
38impl core::fmt::Debug for PacketIdentifier {
39    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
40        self.get().fmt(f)
41    }
42}
43impl core::fmt::Display for PacketIdentifier {
44    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
45        write!(f, "{self:?}")
46    }
47}
48
49#[cfg(feature = "defmt")]
50impl defmt::Format for PacketIdentifier {
51    fn format(&self, fmt: defmt::Formatter) {
52        self.get().format(fmt)
53    }
54}
55
56impl<R: Read> Readable<R> for PacketIdentifier {
57    async fn read(read: &mut R) -> Result<Self, ReadError<<R>::Error>> {
58        u16::read(read)
59            .await
60            .map(NonZero::new)?
61            .map(Self)
62            .ok_or(ReadError::ProtocolError)
63    }
64}
65impl Writable for PacketIdentifier {
66    fn written_len(&self) -> usize {
67        wlen!(u16)
68    }
69
70    async fn write<W: Write>(&self, write: &mut W) -> Result<(), WriteError<W::Error>> {
71        self.get_u16().write(write).await
72    }
73}