Skip to content

Commit

Permalink
Merge pull request #229 from TheNeikos/feature/add_traces
Browse files Browse the repository at this point in the history
Add trace to all parsers
  • Loading branch information
TheNeikos authored Mar 20, 2024
2 parents 1a650b9 + b1d5d75 commit 50307b8
Show file tree
Hide file tree
Showing 22 changed files with 430 additions and 337 deletions.
5 changes: 4 additions & 1 deletion mqtt-format/src/v5/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use winnow::Parser;
use super::MResult;

pub fn parse_binary_data<'i>(input: &mut &'i Bytes) -> MResult<&'i [u8]> {
length_take(super::integers::parse_u16).parse_next(input)
winnow::combinator::trace("mqtt_binary_data", |input: &mut &'i Bytes| {
length_take(super::integers::parse_u16).parse_next(input)
})
.parse_next(input)
}

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions mqtt-format/src/v5/integers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ use super::MResult;

pub fn parse_u16(input: &mut &Bytes) -> MResult<u16> {
trace(
"parse_u16",
"mqtt_u16",
winnow::binary::u16(winnow::binary::Endianness::Big),
)
.parse_next(input)
}

pub fn parse_u32(input: &mut &Bytes) -> MResult<u32> {
trace(
"parse_u32",
"mqtt_u32",
winnow::binary::u32(winnow::binary::Endianness::Big),
)
.parse_next(input)
}

pub fn parse_variable_u32(input: &mut &Bytes) -> MResult<u32> {
trace("parse_variable_u32", |input: &mut &Bytes| {
trace("mqtt_variable_u32", |input: &mut &Bytes| {
let var_bytes = (
take_while(0..=3, |b| b & 0b1000_0000 != 0),
winnow::binary::u8.verify(|b: &u8| b & 0b1000_0000 == 0),
Expand Down
10 changes: 7 additions & 3 deletions mqtt-format/src/v5/packets/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

use winnow::Bytes;
use winnow::Parser;

use crate::v5::variable_header::AuthenticationData;
use crate::v5::variable_header::AuthenticationMethod;
Expand Down Expand Up @@ -47,9 +48,12 @@ pub struct MAuth<'i> {

impl<'i> MAuth<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<Self> {
let reason = AuthReasonCode::parse(input)?;
let properties = AuthProperties::parse(input)?;
winnow::combinator::trace("MAuth", |input: &mut &'i Bytes| {
let reason = AuthReasonCode::parse(input)?;
let properties = AuthProperties::parse(input)?;

Ok(Self { reason, properties })
Ok(Self { reason, properties })
})
.parse_next(input)
}
}
37 changes: 20 additions & 17 deletions mqtt-format/src/v5/packets/connack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,26 @@ pub struct MConnack<'i> {

impl<'i> MConnack<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<MConnack<'i>> {
let (session_present, _) =
winnow::binary::bits::bits::<_, _, InputError<(_, usize)>, _, _>((
winnow::binary::bits::take(1usize).map(|b: u8| b == 1),
winnow::binary::bits::pattern(0b000_0000, 7usize),
))
.parse_next(input)
.map_err(|_: ErrMode<InputError<_>>| {
ErrMode::from_error_kind(input, winnow::error::ErrorKind::Slice)
})?;

let reason_code = ConnectReasonCode::parse(input)?;
let properties = ConnackProperties::parse(input)?;

Ok(MConnack {
session_present,
reason_code,
properties,
winnow::combinator::trace("MConnack", |input: &mut &'i Bytes| {
let (session_present, _) =
winnow::binary::bits::bits::<_, _, InputError<(_, usize)>, _, _>((
winnow::binary::bits::take(1usize).map(|b: u8| b == 1),
winnow::binary::bits::pattern(0b000_0000, 7usize),
))
.parse_next(input)
.map_err(|_: ErrMode<InputError<_>>| {
ErrMode::from_error_kind(input, winnow::error::ErrorKind::Slice)
})?;

let reason_code = ConnectReasonCode::parse(input)?;
let properties = ConnackProperties::parse(input)?;

Ok(MConnack {
session_present,
reason_code,
properties,
})
})
.parse_next(input)
}
}
154 changes: 79 additions & 75 deletions mqtt-format/src/v5/packets/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,84 +79,88 @@ crate::v5::properties::define_properties! {
#[doc = crate::v5::util::md_speclink!("_Toc3901033")]
impl<'i> MConnect<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<Self> {
// parse header

// verify the protocol name
let _ = crate::v5::strings::parse_string
.verify(|s: &str| s == "MQTT")
.parse_next(input)?;

// just for verification
let _ = ProtocolLevel::parse
.verify(|lvl: &ProtocolLevel| *lvl == ProtocolLevel::V5)
.parse_next(input)?;

let (
_reserved,
clean_start,
will_flag,
will_qos,
will_retain,
password_flag,
user_name_flag,
) = winnow::binary::bits::bits::<_, _, InputError<(_, usize)>, _, _>((
winnow::binary::bits::pattern(0x0, 1usize),
winnow::binary::bits::bool,
winnow::binary::bits::bool,
winnow::binary::bits::take(2usize).try_map(<QualityOfService as TryFrom<u8>>::try_from),
winnow::binary::bits::bool,
winnow::binary::bits::bool,
winnow::binary::bits::bool,
))
.parse_next(input)
.map_err(|_: ErrMode<InputError<_>>| {
ErrMode::from_error_kind(input, winnow::error::ErrorKind::Slice)
})?;

let keep_alive = parse_u16(input)?;

let properties = ConnectProperties::parse(input)?;

// finished parsing header, now parse payload

let client_identifier = {
let client_identifier = parse_string(input)?;
if client_identifier.is_empty() {
// Generate client ID?
}
client_identifier
};

let will = will_flag
.then(|| {
let properties = ConnectWillProperties::parse(input)?;
let topic = parse_string(input)?;
let payload = crate::v5::bytes::parse_binary_data(input)?;

Ok(Will {
properties,
topic,
payload,
will_qos,
will_retain,
winnow::combinator::trace("MConnect", |input: &mut &'i Bytes| {
// parse header

// verify the protocol name
let _ = crate::v5::strings::parse_string
.verify(|s: &str| s == "MQTT")
.parse_next(input)?;

// just for verification
let _ = ProtocolLevel::parse
.verify(|lvl: &ProtocolLevel| *lvl == ProtocolLevel::V5)
.parse_next(input)?;

let (
_reserved,
clean_start,
will_flag,
will_qos,
will_retain,
password_flag,
user_name_flag,
) = winnow::binary::bits::bits::<_, _, InputError<(_, usize)>, _, _>((
winnow::binary::bits::pattern(0x0, 1usize),
winnow::binary::bits::bool,
winnow::binary::bits::bool,
winnow::binary::bits::take(2usize)
.try_map(<QualityOfService as TryFrom<u8>>::try_from),
winnow::binary::bits::bool,
winnow::binary::bits::bool,
winnow::binary::bits::bool,
))
.parse_next(input)
.map_err(|_: ErrMode<InputError<_>>| {
ErrMode::from_error_kind(input, winnow::error::ErrorKind::Slice)
})?;

let keep_alive = parse_u16(input)?;

let properties = ConnectProperties::parse(input)?;

// finished parsing header, now parse payload

let client_identifier = {
let client_identifier = parse_string(input)?;
if client_identifier.is_empty() {
// Generate client ID?
}
client_identifier
};

let will = will_flag
.then(|| {
let properties = ConnectWillProperties::parse(input)?;
let topic = parse_string(input)?;
let payload = crate::v5::bytes::parse_binary_data(input)?;

Ok(Will {
properties,
topic,
payload,
will_qos,
will_retain,
})
})
.transpose()?;

let username = user_name_flag.then(|| parse_string(input)).transpose()?;
let password = password_flag
.then(|| parse_binary_data(input))
.transpose()?;

Ok(Self {
client_identifier,
username,
password,
will,
clean_start,
properties,
keep_alive,
})
.transpose()?;

let username = user_name_flag.then(|| parse_string(input)).transpose()?;
let password = password_flag
.then(|| parse_binary_data(input))
.transpose()?;

Ok(Self {
client_identifier,
username,
password,
will,
clean_start,
properties,
keep_alive,
})
.parse_next(input)
}
}

Expand Down
13 changes: 8 additions & 5 deletions mqtt-format/src/v5/packets/disconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,15 @@ pub struct MDisconnect<'i> {

impl<'i> MDisconnect<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<MDisconnect<'i>> {
let (reason_code, properties) =
(DisconnectReasonCode::parse, DisconnectProperties::parse).parse_next(input)?;
winnow::combinator::trace("MDisconnect", |input: &mut &'i Bytes| {
let (reason_code, properties) =
(DisconnectReasonCode::parse, DisconnectProperties::parse).parse_next(input)?;

Ok(MDisconnect {
reason_code,
properties,
Ok(MDisconnect {
reason_code,
properties,
})
})
.parse_next(input)
}
}
53 changes: 29 additions & 24 deletions mqtt-format/src/v5/packets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,33 +63,38 @@ pub enum MqttPacket<'i> {

impl<'i> MqttPacket<'i> {
pub fn parse(input: &mut &'i Bytes) -> MResult<Self> {
let fixed_header = MFixedHeader::parse(input)?;
winnow::combinator::trace("MqttPacket", |input: &mut &'i Bytes| {
let fixed_header = MFixedHeader::parse(input)?;

let parse_packet = |input: &mut &'i Bytes| match fixed_header.packet_type {
PacketType::Connect => MConnect::parse(input).map(MqttPacket::from),
PacketType::Connack => MConnack::parse(input).map(MqttPacket::from),
PacketType::Publish { dup, qos, retain } => {
MPublish::parse(dup, qos, retain, input).map(MqttPacket::from)
}
PacketType::Puback => MPuback::parse(input).map(MqttPacket::from),
PacketType::Pubrec => MPubrec::parse(input).map(MqttPacket::from),
PacketType::Pubrel => MPubrel::parse(input).map(MqttPacket::from),
PacketType::Pubcomp => MPubcomp::parse(input).map(MqttPacket::from),
PacketType::Subscribe => MSubscribe::parse(input).map(MqttPacket::from),
PacketType::Suback => MSuback::parse(input).map(MqttPacket::from),
PacketType::Unsubscribe => MUnsubscribe::parse(input).map(MqttPacket::from),
PacketType::Unsuback => MUnsuback::parse(input).map(MqttPacket::from),
PacketType::Pingreq => MPingreq::parse(input).map(MqttPacket::from),
PacketType::Pingresp => MPingresp::parse(input).map(MqttPacket::from),
PacketType::Disconnect => MDisconnect::parse(input).map(MqttPacket::from),
PacketType::Auth => MAuth::parse(input).map(MqttPacket::from),
};
let parse_packet = |input: &mut &'i Bytes| match fixed_header.packet_type {
PacketType::Connect => MConnect::parse(input).map(MqttPacket::from),
PacketType::Connack => MConnack::parse(input).map(MqttPacket::from),
PacketType::Publish { dup, qos, retain } => {
MPublish::parse(dup, qos, retain, input).map(MqttPacket::from)
}
PacketType::Puback => MPuback::parse(input).map(MqttPacket::from),
PacketType::Pubrec => MPubrec::parse(input).map(MqttPacket::from),
PacketType::Pubrel => MPubrel::parse(input).map(MqttPacket::from),
PacketType::Pubcomp => MPubcomp::parse(input).map(MqttPacket::from),
PacketType::Subscribe => MSubscribe::parse(input).map(MqttPacket::from),
PacketType::Suback => MSuback::parse(input).map(MqttPacket::from),
PacketType::Unsubscribe => MUnsubscribe::parse(input).map(MqttPacket::from),
PacketType::Unsuback => MUnsuback::parse(input).map(MqttPacket::from),
PacketType::Pingreq => MPingreq::parse(input).map(MqttPacket::from),
PacketType::Pingresp => MPingresp::parse(input).map(MqttPacket::from),
PacketType::Disconnect => MDisconnect::parse(input).map(MqttPacket::from),
PacketType::Auth => MAuth::parse(input).map(MqttPacket::from),
};

let packet =
winnow::binary::length_and_then(crate::v5::integers::parse_variable_u32, parse_packet)
.parse_next(input)?;
let packet = winnow::binary::length_and_then(
crate::v5::integers::parse_variable_u32,
parse_packet,
)
.parse_next(input)?;

Ok(packet)
Ok(packet)
})
.parse_next(input)
}
}

Expand Down
3 changes: 2 additions & 1 deletion mqtt-format/src/v5/packets/pingreq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct MPingreq;

impl MPingreq {
pub fn parse(input: &mut &Bytes) -> MResult<MPingreq> {
winnow::combinator::eof.map(|_| MPingreq).parse_next(input)
winnow::combinator::trace("MPingreq", winnow::combinator::eof.map(|_| Self))
.parse_next(input)
}
}
4 changes: 3 additions & 1 deletion mqtt-format/src/v5/packets/pingresp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

use winnow::Bytes;
use winnow::Parser;

use crate::v5::MResult;

Expand All @@ -14,6 +15,7 @@ pub struct MPingresp;

impl MPingresp {
pub fn parse(input: &mut &Bytes) -> MResult<Self> {
winnow::combinator::eof(input).map(|_| Self)
winnow::combinator::trace("MPingresp", winnow::combinator::eof.map(|_| Self))
.parse_next(input)
}
}
Loading

0 comments on commit 50307b8

Please sign in to comment.