pub struct GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,{
pub props: Properties,
/* private fields */
}
Expand description
MQTT 5.0 SUBACK packet representation with generic packet ID support
The SUBACK packet is sent by the MQTT server (broker) in response to a SUBSCRIBE packet from a client. It indicates the maximum QoS level that was granted for each subscription or provides reason codes indicating why the subscription failed.
According to MQTT 5.0 specification, the SUBACK packet contains:
- Fixed header with packet type and remaining length
- Variable header with packet identifier, properties, and reason codes
- No payload
§Packet Structure
SUBACK Packet Structure:
+----------------+
| Fixed Header | - Packet type (0x90) and remaining length
+----------------+
| Packet ID | - 2 bytes (or PacketIdType::Buffer size)
+----------------+
| Properties | - Property length + properties
+----------------+
| Reason Codes | - One or more reason codes (1 byte each)
+----------------+
§Reason Codes
Each reason code in the SUBACK packet corresponds to a topic filter in the original SUBSCRIBE packet and indicates the maximum QoS level granted or an error:
Success codes (QoS levels):
0x00
Granted QoS 0 - Maximum QoS 00x01
Granted QoS 1 - Maximum QoS 10x02
Granted QoS 2 - Maximum QoS 2
Error codes:
0x80
Unspecified error0x83
Implementation specific error0x87
Not authorized0x8F
Topic filter invalid0x91
Packet identifier in use0x97
Quota exceeded0x9E
Shared subscriptions not supported0xA1
Subscription identifiers not supported0xA2
Wildcard subscriptions not supported
§Properties
MQTT 5.0 SUBACK packets can include the following properties:
- Reason String: Human readable string for diagnostic purposes
- User Properties: Application-specific name-value pairs
Only one Reason String property is allowed per packet.
§Generic Packet ID Support
This implementation supports generic packet ID types through the PacketIdType
parameter.
While MQTT specification uses 16-bit packet IDs, this allows for extended packet IDs
(e.g., 32-bit) for broker cluster implementations to prevent packet ID exhaustion.
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
// Create a SUBACK with successful subscriptions
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![
SubackReasonCode::GrantedQos1,
SubackReasonCode::GrantedQos2,
])
.build()
.unwrap();
assert_eq!(suback.packet_id(), 42);
assert_eq!(suback.reason_codes().len(), 2);
// Create SUBACK with mixed success and error codes
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(100u16)
.reason_codes(vec![
SubackReasonCode::GrantedQos1,
SubackReasonCode::NotAuthorized,
SubackReasonCode::TopicFilterInvalid,
])
.build()
.unwrap();
// Add properties for diagnostics
let mut props = mqtt::packet::Properties::new();
// props.add(mqtt::packet::Property::ReasonString("Partial success".to_string()));
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(200u16)
.reason_codes(vec![SubackReasonCode::GrantedQos0])
.props(props)
.build()
.unwrap();
// Serialize to bytes for network transmission
let buffers = suback.to_buffers();
Fields§
§props: Properties
MQTT 5.0 properties for the SUBACK packet
Contains optional properties like reason string and user properties. The properties are validated to ensure only allowed properties are included.
Implementations§
Source§impl<PacketIdType> GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
impl<PacketIdType> GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
Sourcepub fn props(&self) -> &Properties
pub fn props(&self) -> &Properties
MQTT 5.0 properties for the SUBACK packet
Contains optional properties like reason string and user properties. The properties are validated to ensure only allowed properties are included.
Source§impl<PacketIdType> GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
impl<PacketIdType> GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
Sourcepub fn builder() -> GenericSubackBuilder<PacketIdType>
pub fn builder() -> GenericSubackBuilder<PacketIdType>
Create a new GenericSubackBuilder for constructing SUBACK packets
Returns a builder instance that allows setting the various fields of a SUBACK packet in a fluent interface style. The builder ensures all required fields are set before creating the final packet.
§Returns
A new GenericSubackBuilder<PacketIdType>
instance
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::GenericSuback::<u16>::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
Sourcepub fn packet_type() -> PacketType
pub fn packet_type() -> PacketType
Get the packet type for SUBACK packets
Returns the constant packet type identifier for SUBACK packets.
This is always PacketType::Suback
for SUBACK packets.
§Returns
The packet type PacketType::Suback
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::packet_type::PacketType;
assert_eq!(mqtt::packet::v5_0::Suback::packet_type(), PacketType::Suback);
Sourcepub fn packet_id(&self) -> PacketIdType
pub fn packet_id(&self) -> PacketIdType
Get the packet identifier from the SUBACK packet
Returns the packet identifier that matches the SUBSCRIBE packet this SUBACK is responding to. The packet identifier is used to correlate the SUBACK with the original SUBSCRIBE request.
§Returns
The packet identifier as PacketIdType
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(1234u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
assert_eq!(suback.packet_id(), 1234);
Sourcepub fn reason_codes(&self) -> Vec<SubackReasonCode>
pub fn reason_codes(&self) -> Vec<SubackReasonCode>
Get the reason codes from the SUBACK packet
Returns a vector of reason codes indicating the result of each subscription request in the original SUBSCRIBE packet. Each reason code corresponds to a topic filter in the SUBSCRIBE packet, in the same order.
Invalid reason code bytes are converted to SubackReasonCode::UnspecifiedError
to maintain packet integrity.
§Returns
A Vec<SubackReasonCode>
containing the subscription results
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![
SubackReasonCode::GrantedQos1,
SubackReasonCode::NotAuthorized,
SubackReasonCode::GrantedQos0,
])
.build()
.unwrap();
let codes = suback.reason_codes();
assert_eq!(codes.len(), 3);
assert_eq!(codes[0], SubackReasonCode::GrantedQos1);
assert_eq!(codes[1], SubackReasonCode::NotAuthorized);
assert_eq!(codes[2], SubackReasonCode::GrantedQos0);
Sourcepub fn parse(data: &[u8]) -> Result<(Self, usize), MqttError>
pub fn parse(data: &[u8]) -> Result<(Self, usize), MqttError>
Parse a SUBACK packet from raw bytes
Parses the variable header and payload of a SUBACK packet from the provided byte buffer. The fixed header should already be parsed before calling this method.
§Arguments
data
- The raw bytes containing the SUBACK packet variable header and payload
§Returns
Returns a tuple containing:
- The parsed
GenericSuback
instance - The number of bytes consumed during parsing
§Errors
Returns MqttError
if:
- The packet is malformed (insufficient bytes, invalid packet ID, invalid reason codes)
- The packet violates protocol rules (no reason codes provided)
- Properties contain invalid or disallowed property types
- Multiple Reason String properties are present
§Examples
use mqtt_protocol_core::mqtt;
// Parse SUBACK packet from network data
let data = &[0x00, 0x10, 0x00, 0x00]; // packet_id=16, no properties, granted QoS 0
let (suback, consumed) = mqtt::packet::v5_0::Suback::parse(data).unwrap();
assert_eq!(suback.packet_id(), 16);
assert_eq!(consumed, 4);
Sourcepub fn size(&self) -> usize
pub fn size(&self) -> usize
Calculate the total size of the SUBACK packet in bytes
Returns the total number of bytes required to represent this SUBACK packet when serialized for network transmission. This includes the fixed header, variable header, and all reason codes.
§Returns
The total packet size in bytes
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
let size = suback.size();
assert!(size > 0);
Sourcepub fn to_buffers(&self) -> Vec<IoSlice<'_>>
pub fn to_buffers(&self) -> Vec<IoSlice<'_>>
Convert the SUBACK packet to I/O buffers for efficient network transmission
Returns a vector of IoSlice
references that can be used with vectored I/O
operations for efficient network transmission without copying data. The buffers
represent the complete SUBACK packet in wire format.
The returned buffers contain the packet in the following order:
- Fixed header (packet type and remaining length)
- Packet identifier
- Property length
- Properties (if any)
- Reason codes
§Returns
A Vec<IoSlice<'_>>
containing references to the packet data
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
let buffers = suback.to_buffers();
// Use buffers for vectored I/O operations
// let bytes_written = socket.write_vectored(&buffers)?;
Trait Implementations§
Source§impl AsConcrete<GenericSuback<u16>> for Packet
impl AsConcrete<GenericSuback<u16>> for Packet
fn as_concrete(&self) -> Option<&Suback>
Source§impl<PacketIdType> Clone for GenericSuback<PacketIdType>
impl<PacketIdType> Clone for GenericSuback<PacketIdType>
Source§fn clone(&self) -> GenericSuback<PacketIdType>
fn clone(&self) -> GenericSuback<PacketIdType>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<PacketIdType> Debug for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Debug trait implementation for GenericSuback
impl<PacketIdType> Debug for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Debug trait implementation for GenericSuback
Provides a debug representation of the SUBACK packet using the same JSON format as the Display trait. This ensures consistent output for logging and debugging.
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
println!("{:?}", suback); // Prints JSON representation
Source§impl<PacketIdType> Display for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Display trait implementation for GenericSuback
impl<PacketIdType> Display for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Display trait implementation for GenericSuback
Provides a human-readable JSON representation of the SUBACK packet. The display format includes the packet type, packet ID, properties (if any), and reason codes.
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
println!("{}", suback); // Prints JSON representation
Source§impl<PacketIdType> From<GenericSuback<PacketIdType>> for GenericPacket<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
impl<PacketIdType> From<GenericSuback<PacketIdType>> for GenericPacket<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Source§fn from(v: GenericSuback<PacketIdType>) -> GenericPacket<PacketIdType>
fn from(v: GenericSuback<PacketIdType>) -> GenericPacket<PacketIdType>
Source§impl<PacketIdType> GenericPacketDisplay for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
GenericPacketDisplay implementation for GenericSuback
impl<PacketIdType> GenericPacketDisplay for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
GenericPacketDisplay implementation for GenericSuback
Provides standardized display formatting for SUBACK packets through the GenericPacketDisplay trait. This allows consistent formatting across different packet types in the library.
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::GenericPacketDisplay;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
// Use trait methods for consistent formatting
println!("{}", format_args!("{}", suback));
Source§impl<PacketIdType> GenericPacketTrait for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
GenericPacketTrait implementation for GenericSuback
impl<PacketIdType> GenericPacketTrait for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
GenericPacketTrait implementation for GenericSuback
Provides the standard packet interface methods for SUBACK packets. This trait allows SUBACK packets to be used polymorphically with other MQTT packet types.
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::GenericPacketTrait;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
// Use trait methods
let size = suback.size();
let buffers = suback.to_buffers();
Source§impl IntoConcreteOwned<GenericSuback<u16>> for Packet
impl IntoConcreteOwned<GenericSuback<u16>> for Packet
fn into_concrete_owned(self) -> Option<Suback>
Source§impl<PacketIdType> PacketKind for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
impl<PacketIdType> PacketKind for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
Source§const IS_CONNECT: bool = false
const IS_CONNECT: bool = false
true
if this is a CONNECT packetSource§const IS_CONNACK: bool = false
const IS_CONNACK: bool = false
true
if this is a CONNACK packetSource§const IS_PUBLISH: bool = false
const IS_PUBLISH: bool = false
true
if this is a PUBLISH packetSource§const IS_PUBCOMP: bool = false
const IS_PUBCOMP: bool = false
true
if this is a PUBCOMP packetSource§const IS_SUBSCRIBE: bool = false
const IS_SUBSCRIBE: bool = false
true
if this is a SUBSCRIBE packetSource§const IS_UNSUBSCRIBE: bool = false
const IS_UNSUBSCRIBE: bool = false
true
if this is an UNSUBSCRIBE packetSource§const IS_UNSUBACK: bool = false
const IS_UNSUBACK: bool = false
true
if this is an UNSUBACK packetSource§const IS_PINGREQ: bool = false
const IS_PINGREQ: bool = false
true
if this is a PINGREQ packetSource§const IS_PINGRESP: bool = false
const IS_PINGRESP: bool = false
true
if this is a PINGRESP packetSource§const IS_DISCONNECT: bool = false
const IS_DISCONNECT: bool = false
true
if this is a DISCONNECT packetSource§impl<PacketIdType> PartialEq for GenericSuback<PacketIdType>
impl<PacketIdType> PartialEq for GenericSuback<PacketIdType>
Source§impl<PacketIdType> Serialize for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Serialize trait implementation for GenericSuback
impl<PacketIdType> Serialize for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
Serialize trait implementation for GenericSuback
Provides JSON serialization support for SUBACK packets. The serialized format includes the packet type, packet ID, properties (if any), and reason codes.
The serialized structure contains:
type
: Always “suback”packet_id
: The packet identifierprops
: Properties object (only if non-empty)reason_codes
: Array of reason codes (only if non-empty)
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::SubackReasonCode;
let suback = mqtt::packet::v5_0::Suback::builder()
.packet_id(42u16)
.reason_codes(vec![SubackReasonCode::GrantedQos1])
.build()
.unwrap();
let json = serde_json::to_string(&suback).unwrap();
// json contains: {"type":"suback","packet_id":42,"reason_codes":["GrantedQos1"]}
Source§impl<PacketIdType> TryInto<GenericSuback<PacketIdType>> for GenericPacket<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
impl<PacketIdType> TryInto<GenericSuback<PacketIdType>> for GenericPacket<PacketIdType>where
PacketIdType: IsPacketId + Serialize,
impl<PacketIdType> Eq for GenericSuback<PacketIdType>
impl<PacketIdType> SendableRole<Any> for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
impl<PacketIdType> SendableRole<Server> for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
impl<PacketIdType> StructuralPartialEq for GenericSuback<PacketIdType>where
PacketIdType: IsPacketId,
Auto Trait Implementations§
impl<PacketIdType> Freeze for GenericSuback<PacketIdType>
impl<PacketIdType> RefUnwindSafe for GenericSuback<PacketIdType>
impl<PacketIdType> Send for GenericSuback<PacketIdType>
impl<PacketIdType> Sync for GenericSuback<PacketIdType>
impl<PacketIdType> Unpin for GenericSuback<PacketIdType>
impl<PacketIdType> UnwindSafe for GenericSuback<PacketIdType>
Blanket Implementations§
Source§impl<T> AsConcrete<T> for T
impl<T> AsConcrete<T> for T
fn as_concrete(&self) -> Option<&T>
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.