gmqtt 0.1.1

A no_std, no_alloc MQTTv5 packet parsing library for embedded devices
Documentation
use crate::{utils::*, MqttError};

const MQTT_V4_PROTOCOL: &[u8] = &[0u8, 4, b'M', b'Q', b'T', b'T', 4];
const MQTT_V5_PROTOCOL: &[u8] = &[0u8, 4, b'M', b'Q', b'T', b'T', 5];

/// Protocol type
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Protocol {
    V4,
    V5,
}

impl Protocol {
    pub fn new(name: &str, level: u8) -> Result<Self, MqttError> {
        match (name, level) {
            ("MQTT", 4) => Ok(Protocol::V4),
            ("MQTT", 5) => Ok(Protocol::V5),
            (_, level) => Err(MqttError::InvalidProtocol(level)),
        }
    }
    pub fn read(buf: &[u8], offset: &mut usize) -> Result<Self, MqttError> {
        let protocol_name = read_str(buf, offset)?;
        let protocol_level = buf[*offset];
        *offset += 1;
        Protocol::new(protocol_name, protocol_level)
    }

    pub fn write(&self, buf: &mut [u8], offset: &mut usize) -> usize {
        match self {
            Protocol::V4 => {
                for &byte in MQTT_V4_PROTOCOL {
                    write_u8(buf, offset, byte);
                }

                MQTT_V4_PROTOCOL.len()
            }
            Protocol::V5 => {
                for &byte in MQTT_V5_PROTOCOL {
                    write_u8(buf, offset, byte);
                }

                MQTT_V5_PROTOCOL.len()
            }
        }
    }
}
#[cfg(test)]
mod tests {
    use super::{Protocol, MQTT_V4_PROTOCOL, MQTT_V5_PROTOCOL};

    fn sample_bytes_mqtt5() -> Vec<u8> {
        vec![
            0x10, // packet type (connect)
            0x1f, // remaining len
            0x00, 0x04, // 4
            0x4d, 0x51, 0x54, 0x54, // MQTT
            0x05, // level
        ]
    }

    #[test]
    fn mqtt_v5_read() {
        let protocol = Protocol::read(&sample_bytes_mqtt5(), &mut 2).unwrap();
        assert_eq!(protocol, Protocol::V5)
    }

    #[test]
    fn mqtt_v5_read_write() {
        let mut buf = [0u8; 7];
        let protocol = Protocol::read(&sample_bytes_mqtt5(), &mut 2).unwrap();
        protocol.write(&mut buf, &mut 0);
        assert_eq!(buf, MQTT_V5_PROTOCOL);
    }

    fn sample_bytes_mqtt4() -> Vec<u8> {
        vec![
            0x10, // packet type (connect)
            0x1f, 0x00, // remaining len
            0x04, // 4
            0x4d, 0x51, 0x54, 0x54, // MQTT
            0x04, // level
        ]
    }
    #[test]
    fn mqtt_v4_read() {
        let protocol = Protocol::read(&sample_bytes_mqtt4(), &mut 2).unwrap();
        assert_eq!(protocol, Protocol::V4)
    }

    #[test]
    fn mqtt_v4_read_write() {
        let mut buf = [0u8; 7];
        let protocol = Protocol::read(&sample_bytes_mqtt4(), &mut 2).unwrap();
        protocol.write(&mut buf, &mut 0);
        assert_eq!(buf, MQTT_V4_PROTOCOL);
    }
}