From 58a3b00e838dcb14d6b7ba4e3cc4227c57e62b9f Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Sun, 21 Feb 2021 06:30:59 +0800 Subject: [PATCH] [#52] refactored Packet trait, replaced with DecodablePacket - splits Packet into EncodablePacket and DecodablePacket - removes default payload() and payload_ref() methods - fixes encoded_length() implementations for all packets - add PublishPacketRef for performance optimization --- examples/sub-client.rs | 2 +- src/encodable.rs | 16 ++--- src/packet/connack.rs | 15 +---- src/packet/connect.rs | 14 +--- src/packet/disconnect.rs | 19 +----- src/packet/mod.rs | 132 +++++++++++++++++++++++++++----------- src/packet/pingreq.rs | 19 +----- src/packet/pingresp.rs | 19 +----- src/packet/puback.rs | 15 +---- src/packet/pubcomp.rs | 15 +---- src/packet/publish.rs | 76 ++++++++++++++++++---- src/packet/pubrec.rs | 15 +---- src/packet/pubrel.rs | 15 +---- src/packet/suback.rs | 14 +--- src/packet/subscribe.rs | 14 +--- src/packet/unsuback.rs | 15 +---- src/packet/unsubscribe.rs | 14 +--- src/topic_name.rs | 10 +++ 18 files changed, 211 insertions(+), 228 deletions(-) diff --git a/examples/sub-client.rs b/examples/sub-client.rs index 9bc9a09..eeb9937 100644 --- a/examples/sub-client.rs +++ b/examples/sub-client.rs @@ -173,7 +173,7 @@ fn main() { info!("Receiving PINGRESP from broker .."); } VariablePacket::PublishPacket(ref publ) => { - let msg = match str::from_utf8(&publ.payload_ref()[..]) { + let msg = match str::from_utf8(publ.payload()) { Ok(msg) => msg, Err(err) => { error!("Failed to decode publish message {:?}", err); diff --git a/src/encodable.rs b/src/encodable.rs index 1753cb8..43a83ed 100644 --- a/src/encodable.rs +++ b/src/encodable.rs @@ -16,14 +16,14 @@ pub trait Encodable { fn encoded_length(&self) -> u32; } -impl Encodable for &T { - fn encode(&self, writer: &mut W) -> io::Result<()> { - (**self).encode(writer) - } - fn encoded_length(&self) -> u32 { - (**self).encoded_length() - } -} +// impl Encodable for &T { +// fn encode(&self, writer: &mut W) -> io::Result<()> { +// (**self).encode(writer) +// } +// fn encoded_length(&self) -> u32 { +// (**self).encoded_length() +// } +// } impl Encodable for Option { fn encode(&self, writer: &mut W) -> io::Result<()> { diff --git a/src/packet/connack.rs b/src/packet/connack.rs index fa2b59e..2f68520 100644 --- a/src/packet/connack.rs +++ b/src/packet/connack.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::{ConnackFlags, ConnectReturnCode}; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `CONNACK` packet @@ -13,7 +13,6 @@ pub struct ConnackPacket { fixed_header: FixedHeader, flags: ConnackFlags, ret_code: ConnectReturnCode, - payload: (), } encodable_packet!(ConnackPacket(flags, ret_code)); @@ -24,7 +23,6 @@ impl ConnackPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::ConnectAcknowledgement), 2), flags: ConnackFlags { session_present }, ret_code, - payload: (), } } @@ -37,17 +35,9 @@ impl ConnackPacket { } } -impl Packet for ConnackPacket { +impl DecodablePacket for ConnackPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let flags: ConnackFlags = Decodable::decode(reader)?; let code: ConnectReturnCode = Decodable::decode(reader)?; @@ -56,7 +46,6 @@ impl Packet for ConnackPacket { fixed_header, flags, ret_code: code, - payload: (), }) } } diff --git a/src/packet/connect.rs b/src/packet/connect.rs index e57e279..d58fd13 100644 --- a/src/packet/connect.rs +++ b/src/packet/connect.rs @@ -6,7 +6,7 @@ use crate::control::variable_header::protocol_level::SPEC_3_1_1; use crate::control::variable_header::{ConnectFlags, KeepAlive, ProtocolLevel, ProtocolName, VariableHeaderError}; use crate::control::{ControlType, FixedHeader, PacketType}; use crate::encodable::VarBytes; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::topic_name::{TopicName, TopicNameDecodeError, TopicNameError}; use crate::{Decodable, Encodable}; @@ -23,7 +23,7 @@ pub struct ConnectPacket { payload: ConnectPacketPayload, } -encodable_packet!(ConnectPacket(protocol_name, protocol_level, flags, keep_alive)); +encodable_packet!(ConnectPacket(protocol_name, protocol_level, flags, keep_alive, payload)); impl ConnectPacket { pub fn new(client_identifier: C) -> ConnectPacket @@ -151,17 +151,9 @@ impl ConnectPacket { } } -impl Packet for ConnectPacket { +impl DecodablePacket for ConnectPacket { type Payload = ConnectPacketPayload; - fn payload(self) -> ConnectPacketPayload { - self.payload - } - - fn payload_ref(&self) -> &ConnectPacketPayload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let protoname: ProtocolName = Decodable::decode(reader)?; let protocol_level: ProtocolLevel = Decodable::decode(reader)?; diff --git a/src/packet/disconnect.rs b/src/packet/disconnect.rs index 62cdd0e..72aa9ac 100644 --- a/src/packet/disconnect.rs +++ b/src/packet/disconnect.rs @@ -3,13 +3,12 @@ use std::io::Read; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; /// `DISCONNECT` packet #[derive(Debug, Eq, PartialEq, Clone)] pub struct DisconnectPacket { fixed_header: FixedHeader, - payload: (), } encodable_packet!(DisconnectPacket()); @@ -18,7 +17,6 @@ impl DisconnectPacket { pub fn new() -> DisconnectPacket { DisconnectPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::Disconnect), 0), - payload: (), } } } @@ -29,21 +27,10 @@ impl Default for DisconnectPacket { } } -impl Packet for DisconnectPacket { +impl DecodablePacket for DisconnectPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(_reader: &mut R, fixed_header: FixedHeader) -> Result> { - Ok(DisconnectPacket { - fixed_header, - payload: (), - }) + Ok(DisconnectPacket { fixed_header }) } } diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 38d7747..8c40c4b 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,6 +1,6 @@ //! Specific packets -use std::fmt; +use std::fmt::{self, Debug}; use std::io::{self, Read, Write}; #[cfg(feature = "tokio")] @@ -15,29 +15,28 @@ use crate::{Decodable, Encodable}; macro_rules! encodable_packet { ($typ:ident($($field:ident),* $(,)?)) => { - impl $crate::encodable::Encodable for $typ { - fn encode(&self, writer: &mut W) -> std::io::Result<()> { - $crate::encodable::Encodable::encode(&self.fixed_header, writer)?; + impl $crate::packet::EncodablePacket for $typ { + fn fixed_header(&self) -> &$crate::control::fixed_header::FixedHeader { + &self.fixed_header + } + + #[allow(unused)] + fn encode_packet(&self, writer: &mut W) -> ::std::io::Result<()> { $($crate::encodable::Encodable::encode(&self.$field, writer)?;)* - $crate::encodable::Encodable::encode(&self.payload, writer)?; Ok(()) } - fn encoded_length(&self) -> u32 { - $crate::encodable::Encodable::encoded_length(&self.fixed_header) + fn encoded_packet_length(&self) -> u32 { + $($crate::encodable::Encodable::encoded_length(&self.$field) +)* + 0 } } - impl $crate::packet::EncodablePacket for $typ {} - impl $typ { - fn encoded_length_noheader(&self) -> u32 { - $($crate::encodable::Encodable::encoded_length(&self.$field) +)* - $crate::encodable::Encodable::encoded_length(&self.payload) - } #[allow(unused)] + #[inline(always)] fn fix_header_remaining_len(&mut self) { - self.fixed_header.remaining_length = self.encoded_length_noheader() + self.fixed_header.remaining_length = $crate::packet::EncodablePacket::encoded_packet_length(self); } } }; @@ -79,24 +78,40 @@ pub mod unsubscribe; /// `&FooPacket`. Different from [`Encodable`] in that it prevents you from accidentally passing /// a type intended to be encoded only as a part of a packet and doesn't have a header, e.g. /// `Vec`. -pub trait EncodablePacket: Encodable {} +pub trait EncodablePacket { + /// Get a reference to `FixedHeader`. All MQTT packet must have a fixed header. + fn fixed_header(&self) -> &FixedHeader; -impl EncodablePacket for &T {} + /// Encodes packet data after fixed header, including variable headers and payload + fn encode_packet(&self, _writer: &mut W) -> io::Result<()> { + Ok(()) + } + + /// Length in bytes for data after fixed header, including variable headers and payload + fn encoded_packet_length(&self) -> u32 { + 0 + } +} + +impl Encodable for T { + fn encode(&self, writer: &mut W) -> io::Result<()> { + self.fixed_header().encode(writer)?; + self.encode_packet(writer) + } -/// Methods for encoding and decoding a packet -pub trait Packet: Encodable + fmt::Debug + Sized + 'static { - type Payload: Encodable + Decodable; + fn encoded_length(&self) -> u32 { + self.fixed_header().encoded_length() + self.encoded_packet_length() + } +} - /// Get the payload - fn payload(self) -> Self::Payload; - /// Get a borrow of payload - fn payload_ref(&self) -> &Self::Payload; +pub trait DecodablePacket: EncodablePacket + Sized { + type Payload: Decodable + 'static; /// Decode packet given a `FixedHeader` fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result>; } -impl Decodable for T { +impl Decodable for T { type Error = PacketError; type Cond = Option; @@ -107,22 +122,41 @@ impl Decodable for T { Decodable::decode(reader)? }; - ::decode_packet(reader, fixed_header) + ::decode_packet(reader, fixed_header) } } /// Parsing errors for packet -#[derive(Debug, thiserror::Error)] +#[derive(thiserror::Error)] #[error(transparent)] -pub enum PacketError { +pub enum PacketError

+where + P: DecodablePacket, +{ FixedHeaderError(#[from] FixedHeaderError), VariableHeaderError(#[from] VariableHeaderError), - PayloadError(<

::Payload as Decodable>::Error), + PayloadError(<

::Payload as Decodable>::Error), IoError(#[from] io::Error), TopicNameError(#[from] TopicNameError), } -impl From for PacketError

{ +impl

Debug for PacketError

+where + P: DecodablePacket, + ::Error: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + PacketError::FixedHeaderError(ref e) => f.debug_tuple("FixedHeaderError").field(e).finish(), + PacketError::VariableHeaderError(ref e) => f.debug_tuple("VariableHeaderError").field(e).finish(), + PacketError::PayloadError(ref e) => f.debug_tuple("PayloadError").field(e).finish(), + PacketError::IoError(ref e) => f.debug_tuple("IoError").field(e).finish(), + PacketError::TopicNameError(ref e) => f.debug_tuple("TopicNameError").field(e).finish(), + } + } +} + +impl From for PacketError

{ fn from(e: TopicNameDecodeError) -> Self { match e { TopicNameDecodeError::IoError(e) => e.into(), @@ -162,7 +196,7 @@ macro_rules! impl_variable_packet { match fixed_header.packet_type.control_type { $( ControlType::$hdr => { - let pk = <$name as Packet>::decode_packet(rdr, fixed_header)?; + let pk = <$name as DecodablePacket>::decode_packet(rdr, fixed_header)?; Ok(VariablePacket::$name(pk)) } )+ @@ -177,25 +211,49 @@ macro_rules! impl_variable_packet { } )+ - impl Encodable for VariablePacket { - fn encode(&self, writer: &mut W) -> Result<(), io::Error> { + // impl Encodable for VariablePacket { + // fn encode(&self, writer: &mut W) -> Result<(), io::Error> { + // match *self { + // $( + // VariablePacket::$name(ref pk) => pk.encode(writer), + // )+ + // } + // } + + // fn encoded_length(&self) -> u32 { + // match *self { + // $( + // VariablePacket::$name(ref pk) => pk.encoded_length(), + // )+ + // } + // } + // } + + impl EncodablePacket for VariablePacket { + fn fixed_header(&self) -> &FixedHeader { match *self { $( - VariablePacket::$name(ref pk) => pk.encode(writer), + VariablePacket::$name(ref pk) => pk.fixed_header(), )+ } } - fn encoded_length(&self) -> u32 { + fn encode_packet(&self, writer: &mut W) -> io::Result<()> { match *self { $( - VariablePacket::$name(ref pk) => pk.encoded_length(), + VariablePacket::$name(ref pk) => pk.encode_packet(writer), )+ } } - } - impl EncodablePacket for VariablePacket {} + fn encoded_packet_length(&self) -> u32 { + match *self { + $( + VariablePacket::$name(ref pk) => pk.encoded_packet_length(), + )+ + } + } + } impl Decodable for VariablePacket { type Error = VariablePacketError; diff --git a/src/packet/pingreq.rs b/src/packet/pingreq.rs index 4ae6ad4..ab35c0f 100644 --- a/src/packet/pingreq.rs +++ b/src/packet/pingreq.rs @@ -3,13 +3,12 @@ use std::io::Read; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; /// `PINGREQ` packet #[derive(Debug, Eq, PartialEq, Clone)] pub struct PingreqPacket { fixed_header: FixedHeader, - payload: (), } encodable_packet!(PingreqPacket()); @@ -18,7 +17,6 @@ impl PingreqPacket { pub fn new() -> PingreqPacket { PingreqPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PingRequest), 0), - payload: (), } } } @@ -29,21 +27,10 @@ impl Default for PingreqPacket { } } -impl Packet for PingreqPacket { +impl DecodablePacket for PingreqPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(_reader: &mut R, fixed_header: FixedHeader) -> Result> { - Ok(PingreqPacket { - fixed_header, - payload: (), - }) + Ok(PingreqPacket { fixed_header }) } } diff --git a/src/packet/pingresp.rs b/src/packet/pingresp.rs index 9f14ad4..2fdbacb 100644 --- a/src/packet/pingresp.rs +++ b/src/packet/pingresp.rs @@ -3,13 +3,12 @@ use std::io::Read; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; /// `PINGRESP` packet #[derive(Debug, Eq, PartialEq, Clone)] pub struct PingrespPacket { fixed_header: FixedHeader, - payload: (), } encodable_packet!(PingrespPacket()); @@ -18,7 +17,6 @@ impl PingrespPacket { pub fn new() -> PingrespPacket { PingrespPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PingResponse), 0), - payload: (), } } } @@ -29,21 +27,10 @@ impl Default for PingrespPacket { } } -impl Packet for PingrespPacket { +impl DecodablePacket for PingrespPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(_reader: &mut R, fixed_header: FixedHeader) -> Result> { - Ok(PingrespPacket { - fixed_header, - payload: (), - }) + Ok(PingrespPacket { fixed_header }) } } diff --git a/src/packet/puback.rs b/src/packet/puback.rs index 8668826..2d6792e 100644 --- a/src/packet/puback.rs +++ b/src/packet/puback.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `PUBACK` packet @@ -12,7 +12,6 @@ use crate::Decodable; pub struct PubackPacket { fixed_header: FixedHeader, packet_identifier: PacketIdentifier, - payload: (), } encodable_packet!(PubackPacket(packet_identifier)); @@ -22,7 +21,6 @@ impl PubackPacket { PubackPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PublishAcknowledgement), 2), packet_identifier: PacketIdentifier(pkid), - payload: (), } } @@ -35,23 +33,14 @@ impl PubackPacket { } } -impl Packet for PubackPacket { +impl DecodablePacket for PubackPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; Ok(PubackPacket { fixed_header, packet_identifier, - payload: (), }) } } diff --git a/src/packet/pubcomp.rs b/src/packet/pubcomp.rs index 07ffa00..3211045 100644 --- a/src/packet/pubcomp.rs +++ b/src/packet/pubcomp.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `PUBCOMP` packet @@ -12,7 +12,6 @@ use crate::Decodable; pub struct PubcompPacket { fixed_header: FixedHeader, packet_identifier: PacketIdentifier, - payload: (), } encodable_packet!(PubcompPacket(packet_identifier)); @@ -22,7 +21,6 @@ impl PubcompPacket { PubcompPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PublishComplete), 2), packet_identifier: PacketIdentifier(pkid), - payload: (), } } @@ -35,23 +33,14 @@ impl PubcompPacket { } } -impl Packet for PubcompPacket { +impl DecodablePacket for PubcompPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; Ok(PubcompPacket { fixed_header, packet_identifier, - payload: (), }) } } diff --git a/src/packet/publish.rs b/src/packet/publish.rs index 2f1d050..3fcb320 100644 --- a/src/packet/publish.rs +++ b/src/packet/publish.rs @@ -1,14 +1,16 @@ //! PUBLISH -use std::io::Read; +use std::io::{self, Read, Write}; -use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::qos::QualityOfService; use crate::topic_name::TopicName; +use crate::{control::variable_header::PacketIdentifier, TopicNameRef}; use crate::{Decodable, Encodable}; +use super::EncodablePacket; + /// QoS with identifier pairs #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] pub enum QoSWithPacketIdentifier { @@ -36,7 +38,7 @@ pub struct PublishPacket { payload: Vec, } -encodable_packet!(PublishPacket(topic_name, packet_identifier)); +encodable_packet!(PublishPacket(topic_name, packet_identifier, payload)); impl PublishPacket { pub fn new>>(topic_name: TopicName, qos: QoSWithPacketIdentifier, payload: P) -> PublishPacket { @@ -105,18 +107,19 @@ impl PublishPacket { pub fn topic_name(&self) -> &str { &self.topic_name[..] } -} -impl Packet for PublishPacket { - type Payload = Vec; - - fn payload(self) -> Self::Payload { - self.payload + pub fn payload(&self) -> &[u8] { + &self.payload } - fn payload_ref(&self) -> &Self::Payload { - &self.payload + pub fn set_payload>>(&mut self, payload: P) { + self.payload = payload.into(); + self.fix_header_remaining_len(); } +} + +impl DecodablePacket for PublishPacket { + type Payload = Vec; fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let topic_name = TopicName::decode(reader)?; @@ -142,6 +145,55 @@ impl Packet for PublishPacket { } } +/// `PUBLISH` packet by reference, for encoding only +pub struct PublishPacketRef<'a> { + fixed_header: FixedHeader, + topic_name: &'a TopicNameRef, + packet_identifier: Option, + payload: &'a [u8], +} + +impl<'a> PublishPacketRef<'a> { + pub fn new(topic_name: &'a TopicNameRef, qos: QoSWithPacketIdentifier, payload: &'a [u8]) -> PublishPacketRef<'a> { + let (qos, pkid) = match qos { + QoSWithPacketIdentifier::Level0 => (0, None), + QoSWithPacketIdentifier::Level1(pkid) => (1, Some(PacketIdentifier(pkid))), + QoSWithPacketIdentifier::Level2(pkid) => (2, Some(PacketIdentifier(pkid))), + }; + + let mut pk = PublishPacketRef { + fixed_header: FixedHeader::new(PacketType::with_default(ControlType::Publish), 0), + topic_name, + packet_identifier: pkid, + payload, + }; + pk.fixed_header.packet_type.flags |= qos << 1; + pk.fix_header_remaining_len(); + pk + } + + fn fix_header_remaining_len(&mut self) { + self.fixed_header.remaining_length = + self.topic_name.encoded_length() + self.packet_identifier.encoded_length() + self.payload.encoded_length(); + } +} + +impl EncodablePacket for PublishPacketRef<'_> { + fn fixed_header(&self) -> &FixedHeader { + &self.fixed_header + } + + fn encode_packet(&self, writer: &mut W) -> io::Result<()> { + self.topic_name.encode(writer)?; + self.packet_identifier.encode(writer)?; + self.payload.encode(writer) + } + + fn encoded_packet_length(&self) -> u32 { + self.topic_name.encoded_length() + self.packet_identifier.encoded_length() + self.payload.encoded_length() + } +} + #[cfg(test)] mod test { use super::*; diff --git a/src/packet/pubrec.rs b/src/packet/pubrec.rs index 8d138da..2c362e1 100644 --- a/src/packet/pubrec.rs +++ b/src/packet/pubrec.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `PUBREC` packet @@ -12,7 +12,6 @@ use crate::Decodable; pub struct PubrecPacket { fixed_header: FixedHeader, packet_identifier: PacketIdentifier, - payload: (), } encodable_packet!(PubrecPacket(packet_identifier)); @@ -22,7 +21,6 @@ impl PubrecPacket { PubrecPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PublishReceived), 2), packet_identifier: PacketIdentifier(pkid), - payload: (), } } @@ -35,23 +33,14 @@ impl PubrecPacket { } } -impl Packet for PubrecPacket { +impl DecodablePacket for PubrecPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; Ok(PubrecPacket { fixed_header, packet_identifier, - payload: (), }) } } diff --git a/src/packet/pubrel.rs b/src/packet/pubrel.rs index 70b6094..b6be49c 100644 --- a/src/packet/pubrel.rs +++ b/src/packet/pubrel.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `PUBREL` packet @@ -12,7 +12,6 @@ use crate::Decodable; pub struct PubrelPacket { fixed_header: FixedHeader, packet_identifier: PacketIdentifier, - payload: (), } encodable_packet!(PubrelPacket(packet_identifier)); @@ -22,7 +21,6 @@ impl PubrelPacket { PubrelPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::PublishRelease), 2), packet_identifier: PacketIdentifier(pkid), - payload: (), } } @@ -35,23 +33,14 @@ impl PubrelPacket { } } -impl Packet for PubrelPacket { +impl DecodablePacket for PubrelPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; Ok(PubrelPacket { fixed_header, packet_identifier, - payload: (), }) } } diff --git a/src/packet/suback.rs b/src/packet/suback.rs index 16daed7..0725a70 100644 --- a/src/packet/suback.rs +++ b/src/packet/suback.rs @@ -8,7 +8,7 @@ use byteorder::{ReadBytesExt, WriteBytesExt}; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::qos::QualityOfService; use crate::{Decodable, Encodable}; @@ -57,7 +57,7 @@ pub struct SubackPacket { payload: SubackPacketPayload, } -encodable_packet!(SubackPacket(packet_identifier)); +encodable_packet!(SubackPacket(packet_identifier, payload)); impl SubackPacket { pub fn new(pkid: u16, subscribes: Vec) -> SubackPacket { @@ -79,17 +79,9 @@ impl SubackPacket { } } -impl Packet for SubackPacket { +impl DecodablePacket for SubackPacket { type Payload = SubackPacketPayload; - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier = PacketIdentifier::decode(reader)?; let payload: SubackPacketPayload = SubackPacketPayload::decode_with( diff --git a/src/packet/subscribe.rs b/src/packet/subscribe.rs index c756f3b..2bec1aa 100644 --- a/src/packet/subscribe.rs +++ b/src/packet/subscribe.rs @@ -7,7 +7,7 @@ use byteorder::{ReadBytesExt, WriteBytesExt}; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::topic_filter::{TopicFilter, TopicFilterDecodeError, TopicFilterError}; use crate::{Decodable, Encodable, QualityOfService}; @@ -19,7 +19,7 @@ pub struct SubscribePacket { payload: SubscribePacketPayload, } -encodable_packet!(SubscribePacket(packet_identifier)); +encodable_packet!(SubscribePacket(packet_identifier, payload)); impl SubscribePacket { pub fn new(pkid: u16, subscribes: Vec<(TopicFilter, QualityOfService)>) -> SubscribePacket { @@ -41,17 +41,9 @@ impl SubscribePacket { } } -impl Packet for SubscribePacket { +impl DecodablePacket for SubscribePacket { type Payload = SubscribePacketPayload; - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; let payload: SubscribePacketPayload = SubscribePacketPayload::decode_with( diff --git a/src/packet/unsuback.rs b/src/packet/unsuback.rs index 54af3a0..4fb3c22 100644 --- a/src/packet/unsuback.rs +++ b/src/packet/unsuback.rs @@ -4,7 +4,7 @@ use std::io::Read; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::Decodable; /// `UNSUBACK` packet @@ -12,7 +12,6 @@ use crate::Decodable; pub struct UnsubackPacket { fixed_header: FixedHeader, packet_identifier: PacketIdentifier, - payload: (), } encodable_packet!(UnsubackPacket(packet_identifier)); @@ -22,7 +21,6 @@ impl UnsubackPacket { UnsubackPacket { fixed_header: FixedHeader::new(PacketType::with_default(ControlType::UnsubscribeAcknowledgement), 2), packet_identifier: PacketIdentifier(pkid), - payload: (), } } @@ -35,23 +33,14 @@ impl UnsubackPacket { } } -impl Packet for UnsubackPacket { +impl DecodablePacket for UnsubackPacket { type Payload = (); - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; Ok(UnsubackPacket { fixed_header, packet_identifier, - payload: (), }) } } diff --git a/src/packet/unsubscribe.rs b/src/packet/unsubscribe.rs index ec6eebe..860a355 100644 --- a/src/packet/unsubscribe.rs +++ b/src/packet/unsubscribe.rs @@ -5,7 +5,7 @@ use std::string::FromUtf8Error; use crate::control::variable_header::PacketIdentifier; use crate::control::{ControlType, FixedHeader, PacketType}; -use crate::packet::{Packet, PacketError}; +use crate::packet::{DecodablePacket, PacketError}; use crate::topic_filter::{TopicFilter, TopicFilterDecodeError, TopicFilterError}; use crate::{Decodable, Encodable}; @@ -17,7 +17,7 @@ pub struct UnsubscribePacket { payload: UnsubscribePacketPayload, } -encodable_packet!(UnsubscribePacket(packet_identifier)); +encodable_packet!(UnsubscribePacket(packet_identifier, payload)); impl UnsubscribePacket { pub fn new(pkid: u16, subscribes: Vec) -> UnsubscribePacket { @@ -39,17 +39,9 @@ impl UnsubscribePacket { } } -impl Packet for UnsubscribePacket { +impl DecodablePacket for UnsubscribePacket { type Payload = UnsubscribePacketPayload; - fn payload(self) -> Self::Payload { - self.payload - } - - fn payload_ref(&self) -> &Self::Payload { - &self.payload - } - fn decode_packet(reader: &mut R, fixed_header: FixedHeader) -> Result> { let packet_identifier: PacketIdentifier = PacketIdentifier::decode(reader)?; let payload: UnsubscribePacketPayload = UnsubscribePacketPayload::decode_with( diff --git a/src/topic_name.rs b/src/topic_name.rs index 3ace7f8..f7afe2b 100644 --- a/src/topic_name.rs +++ b/src/topic_name.rs @@ -189,6 +189,16 @@ impl ToOwned for TopicNameRef { } } +impl Encodable for TopicNameRef { + fn encode(&self, writer: &mut W) -> Result<(), io::Error> { + (&self.0[..]).encode(writer) + } + + fn encoded_length(&self) -> u32 { + (&self.0[..]).encoded_length() + } +} + #[cfg(test)] mod test { use super::*;