mqtt_codec_kit/common/variable_header/
protocol_level.rs

1//! Protocol level header
2
3use std::io::{self, Read, Write};
4
5use byteorder::{ReadBytesExt, WriteBytesExt};
6
7use crate::common::{Decodable, Encodable};
8
9pub const SPEC_3_1_0: u8 = 0x03;
10pub const SPEC_3_1_1: u8 = 0x04;
11pub const SPEC_5_0: u8 = 0x05;
12
13/// Protocol level in MQTT (`0x04` in v3.1.1)
14#[derive(Debug, Eq, PartialEq, Copy, Clone)]
15#[repr(u8)]
16pub enum ProtocolLevel {
17    Version310 = SPEC_3_1_0,
18    Version311 = SPEC_3_1_1,
19    Version50 = SPEC_5_0,
20}
21
22impl TryFrom<u8> for ProtocolLevel {
23    type Error = ProtocolLevelError;
24
25    fn try_from(value: u8) -> Result<Self, Self::Error> {
26        match value {
27            SPEC_3_1_0 => Ok(ProtocolLevel::Version310),
28            SPEC_3_1_1 => Ok(ProtocolLevel::Version311),
29            SPEC_5_0 => Ok(ProtocolLevel::Version50),
30            lvl => Err(ProtocolLevelError::InvalidProtocolLevel(lvl)),
31        }
32    }
33}
34
35impl Encodable for ProtocolLevel {
36    fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
37        writer.write_u8(*self as u8)
38    }
39
40    fn encoded_length(&self) -> u32 {
41        1
42    }
43}
44
45impl Decodable for ProtocolLevel {
46    type Error = ProtocolLevelError;
47    type Cond = ();
48
49    fn decode_with<R: Read>(
50        reader: &mut R,
51        _rest: (),
52    ) -> Result<ProtocolLevel, ProtocolLevelError> {
53        reader.read_u8().map(ProtocolLevel::try_from)?
54    }
55}
56
57#[derive(Debug, thiserror::Error)]
58#[error(transparent)]
59pub enum ProtocolLevelError {
60    IoError(#[from] io::Error),
61    #[error("invalid protocol level ({0})")]
62    InvalidProtocolLevel(u8),
63}