summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Müller <neikos@neikos.email>2024-03-20 18:03:59 +0100
committerGitHub <noreply@github.com>2024-03-20 18:03:59 +0100
commita5aee6b35518ec54bd66b3d14c32f905cfe1852f (patch)
treefbf6fc68878769c85a0096d93eb7cdf8337d59dc
parent8ea3e0cdf8b37331fbdb03c106daff02d1db93eb (diff)
parent861502c7efad19667b4d97b8a5b0772bbbfc5b3d (diff)
Merge pull request #233 from TheNeikos/feature/add_docs
Feature/add docs
-rw-r--r--mqtt-format/src/lib.rs1
-rw-r--r--mqtt-format/src/v5/bytes.rs1
-rw-r--r--mqtt-format/src/v5/fixed_header.rs1
-rw-r--r--mqtt-format/src/v5/integers.rs17
-rw-r--r--mqtt-format/src/v5/level.rs30
-rw-r--r--mqtt-format/src/v5/mod.rs30
-rw-r--r--mqtt-format/src/v5/packets/connect.rs20
-rw-r--r--mqtt-format/src/v5/packets/mod.rs1
-rw-r--r--mqtt-format/src/v5/properties.rs1
-rw-r--r--mqtt-format/src/v5/reason_code.rs1
-rw-r--r--mqtt-format/src/v5/strings.rs13
-rw-r--r--mqtt-format/src/v5/variable_header.rs3
12 files changed, 84 insertions, 35 deletions
diff --git a/mqtt-format/src/lib.rs b/mqtt-format/src/lib.rs
index bed8140..960ab54 100644
--- a/mqtt-format/src/lib.rs
+++ b/mqtt-format/src/lib.rs
@@ -9,5 +9,6 @@
#[cfg(feature = "mqttv3")]
pub mod v3;
+
#[cfg(feature = "mqttv5")]
pub mod v5;
diff --git a/mqtt-format/src/v5/bytes.rs b/mqtt-format/src/v5/bytes.rs
index f9a2a01..b1623c2 100644
--- a/mqtt-format/src/v5/bytes.rs
+++ b/mqtt-format/src/v5/bytes.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Ways to parse MQTT byte data
use winnow::binary::length_take;
use winnow::Bytes;
diff --git a/mqtt-format/src/v5/fixed_header.rs b/mqtt-format/src/v5/fixed_header.rs
index eb90204..ed0ba85 100644
--- a/mqtt-format/src/v5/fixed_header.rs
+++ b/mqtt-format/src/v5/fixed_header.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Everything around parsing the fixed MQTT Header
use winnow::binary::bits::bits;
use winnow::error::ErrMode;
diff --git a/mqtt-format/src/v5/integers.rs b/mqtt-format/src/v5/integers.rs
index 96fa8aa..91990cc 100644
--- a/mqtt-format/src/v5/integers.rs
+++ b/mqtt-format/src/v5/integers.rs
@@ -3,6 +3,9 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Various ways to parse MQTT integers
+//!
+//! All integers in MQTT are big-endian
use winnow::combinator::trace;
use winnow::token::take_while;
@@ -11,6 +14,10 @@ use winnow::Parser;
use super::MResult;
+/// Parse a u16
+///
+/// MQTT expects their numbers in big-endian
+#[doc = crate::v5::util::md_speclink!("_Toc3901008")]
pub fn parse_u16(input: &mut &Bytes) -> MResult<u16> {
trace(
"mqtt_u16",
@@ -19,6 +26,10 @@ pub fn parse_u16(input: &mut &Bytes) -> MResult<u16> {
.parse_next(input)
}
+/// Parse a u32
+///
+/// MQTT expects their numbers in big-endian
+#[doc = crate::v5::util::md_speclink!("_Toc3901009")]
pub fn parse_u32(input: &mut &Bytes) -> MResult<u32> {
trace(
"mqtt_u32",
@@ -27,6 +38,12 @@ pub fn parse_u32(input: &mut &Bytes) -> MResult<u32> {
.parse_next(input)
}
+/// Parse a variable sized integer
+///
+/// Value range: `0..268_435_455`
+/// The maximal value is smaller than a u32, so that type is used
+///
+#[doc = crate::v5::util::md_speclink!("_Toc3901011")]
pub fn parse_variable_u32(input: &mut &Bytes) -> MResult<u32> {
trace("mqtt_variable_u32", |input: &mut &Bytes| {
let var_bytes = (
diff --git a/mqtt-format/src/v5/level.rs b/mqtt-format/src/v5/level.rs
deleted file mode 100644
index 7e54eef..0000000
--- a/mqtt-format/src/v5/level.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-//
-
-use winnow::error::ErrMode;
-use winnow::error::ParserError;
-use winnow::Bytes;
-
-use super::MResult;
-
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum ProtocolLevel {
- V3,
- V5,
-}
-
-impl ProtocolLevel {
- pub fn parse(input: &mut &Bytes) -> MResult<Self> {
- match winnow::binary::u8(input)? {
- 3 => Ok(Self::V3),
- 5 => Ok(Self::V5),
- _ => Err(ErrMode::from_error_kind(
- input,
- winnow::error::ErrorKind::Verify,
- )),
- }
- }
-}
diff --git a/mqtt-format/src/v5/mod.rs b/mqtt-format/src/v5/mod.rs
index b11a53a..1152790 100644
--- a/mqtt-format/src/v5/mod.rs
+++ b/mqtt-format/src/v5/mod.rs
@@ -8,15 +8,41 @@
#![deny(clippy::std_instead_of_core)]
#![deny(clippy::alloc_instead_of_core)]
+//! MQTTv5 binary format parsing
+//!
+#![doc = util::md_speclink!("_Toc3901000")]
+//!
+//! The main entry point of the v5 module is found in [packets::MqttPacket] and its associated
+//! [packets::MqttPacket::parse_complete] method.
+//!
+//! This allows to retrieve a zero-copy deserialized form of a single MQTTPacket.
+//! All protocol-level invariants are checked here. Nonetheless, dynamic protocol violations cannot
+//! be detected at this level, and as such fall onto the responsibility of the user.
+//!
+//! # Example
+//!
+//! ```rust
+//! use mqtt_format::v5::packets::MqttPacket;
+//!# // A PINGREQ packet
+//!# fn read_input() -> &'static [u8] { &[0b1100_0000, 0x0] }
+//! let input: &[u8] = read_input();
+//!
+//! let packet = MqttPacket::parse_complete(input).expect("A valid MQTT Packet");
+//!
+//! match packet {
+//! MqttPacket::Pingreq(_) => println!("Got a PINGREQ!"),
+//! packet => panic!("Got an unexpected packet: {packet:?}"),
+//! }
+//! ```
+
pub mod bytes;
pub mod fixed_header;
pub mod integers;
-pub mod level;
pub mod packets;
pub mod properties;
pub mod reason_code;
pub mod strings;
-pub mod util;
+mod util;
pub mod variable_header;
pub type MResult<O> = winnow::PResult<O>;
diff --git a/mqtt-format/src/v5/packets/connect.rs b/mqtt-format/src/v5/packets/connect.rs
index fa90f77..61a9901 100644
--- a/mqtt-format/src/v5/packets/connect.rs
+++ b/mqtt-format/src/v5/packets/connect.rs
@@ -13,7 +13,6 @@ use winnow::Parser;
use crate::v5::bytes::parse_binary_data;
use crate::v5::fixed_header::QualityOfService;
use crate::v5::integers::parse_u16;
-use crate::v5::level::ProtocolLevel;
use crate::v5::strings::parse_string;
use crate::v5::variable_header::AuthenticationData;
use crate::v5::variable_header::AuthenticationMethod;
@@ -183,3 +182,22 @@ crate::v5::properties::define_properties! {
correlation_data: CorrelationData<'i>,
}
}
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum ProtocolLevel {
+ V3,
+ V5,
+}
+
+impl ProtocolLevel {
+ pub fn parse(input: &mut &Bytes) -> MResult<Self> {
+ match winnow::binary::u8(input)? {
+ 3 => Ok(Self::V3),
+ 5 => Ok(Self::V5),
+ _ => Err(ErrMode::from_error_kind(
+ input,
+ winnow::error::ErrorKind::Verify,
+ )),
+ }
+ }
+}
diff --git a/mqtt-format/src/v5/packets/mod.rs b/mqtt-format/src/v5/packets/mod.rs
index 6b7737c..5988b11 100644
--- a/mqtt-format/src/v5/packets/mod.rs
+++ b/mqtt-format/src/v5/packets/mod.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Handling of MQTT Control Packets
use winnow::error::ContextError;
use winnow::error::ErrMode;
diff --git a/mqtt-format/src/v5/properties.rs b/mqtt-format/src/v5/properties.rs
index 3ab5796..506deb5 100644
--- a/mqtt-format/src/v5/properties.rs
+++ b/mqtt-format/src/v5/properties.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Handling of MQTT Properties that are present in some packets
use winnow::error::ErrMode;
use winnow::error::ParserError;
diff --git a/mqtt-format/src/v5/reason_code.rs b/mqtt-format/src/v5/reason_code.rs
index ea36000..10d88f2 100644
--- a/mqtt-format/src/v5/reason_code.rs
+++ b/mqtt-format/src/v5/reason_code.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Handling reason codes that are present in some packets
macro_rules! make_combined_reason_code {
(pub enum $name:ident {
diff --git a/mqtt-format/src/v5/strings.rs b/mqtt-format/src/v5/strings.rs
index 48fb102..91c81e1 100644
--- a/mqtt-format/src/v5/strings.rs
+++ b/mqtt-format/src/v5/strings.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Various ways to parse MQTT Strings
use winnow::binary::length_take;
use winnow::error::ErrMode;
@@ -13,6 +14,11 @@ use winnow::Parser;
use super::integers::parse_u16;
use super::MResult;
+/// Parse an UTF-8 String
+///
+/// MQTT expects that all Strings are UTF-8 encoded
+///
+#[doc = crate::v5::util::md_speclink!("_Toc3901010")]
pub fn parse_string<'i>(input: &mut &'i Bytes) -> MResult<&'i str> {
winnow::combinator::trace("mqtt_string", |input: &mut &'i Bytes| {
let maybe_str = length_take(parse_u16).parse_next(input)?;
@@ -23,7 +29,12 @@ pub fn parse_string<'i>(input: &mut &'i Bytes) -> MResult<&'i str> {
.parse_next(input)
}
-pub fn string_pair<'i>(input: &mut &'i Bytes) -> MResult<(&'i str, &'i str)> {
+/// Parse a pair of UTF-8 Strings
+///
+/// MQTT expects that all Strings are UTF-8 encoded
+///
+#[doc = crate::v5::util::md_speclink!("_Toc3901013")]
+pub fn parse_string_pair<'i>(input: &mut &'i Bytes) -> MResult<(&'i str, &'i str)> {
winnow::combinator::trace("mqtt_string_pair", |input: &mut &'i Bytes| {
let first = parse_string(input)?;
let second = parse_string(input)?;
diff --git a/mqtt-format/src/v5/variable_header.rs b/mqtt-format/src/v5/variable_header.rs
index fca22e0..011efe3 100644
--- a/mqtt-format/src/v5/variable_header.rs
+++ b/mqtt-format/src/v5/variable_header.rs
@@ -3,6 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
+//! Various components present in MQTT variable headers
use winnow::Bytes;
use winnow::Parser;
@@ -175,7 +176,7 @@ pub struct UserProperty<'i> {
impl<'i> UserProperty<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<UserProperty<'i>> {
winnow::combinator::trace("UserProperty", |input: &mut &'i Bytes| {
- crate::v5::strings::string_pair
+ crate::v5::strings::parse_string_pair
.map(|(k, v)| UserProperty { key: k, value: v })
.parse_next(input)
})