Struct GenericUnsuback

Source
pub struct GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,
{ pub props: Properties, /* private fields */ }
Expand description

MQTT 5.0 UNSUBACK packet representation with generic packet ID support

The UNSUBACK packet is sent by the MQTT server (broker) in response to an UNSUBSCRIBE packet from a client. It indicates the result of each unsubscription request and confirms that the client has been unsubscribed from the specified topic filters.

According to MQTT 5.0 specification, the UNSUBACK packet contains:

  • Fixed header with packet type and remaining length
  • Variable header with packet identifier, properties, and reason codes
  • No payload

§Packet Structure

UNSUBACK Packet Structure:
+----------------+
| Fixed Header   |  - Packet type (0xB0) 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 UNSUBACK packet corresponds to a topic filter in the original UNSUBSCRIBE packet and indicates the result of the unsubscription request:

Success codes:

  • 0x00 Success - The unsubscription was successful
  • 0x11 No subscription existed - No matching subscription found

Error codes:

  • 0x80 Unspecified error - An unspecified error occurred
  • 0x83 Implementation specific error - Server implementation specific error
  • 0x87 Not authorized - The client is not authorized to unsubscribe
  • 0x8F Topic filter invalid - The topic filter is malformed
  • 0x91 Packet identifier in use - The packet identifier is already in use

§Properties

MQTT 5.0 UNSUBACK 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::UnsubackReasonCode;

// Create an UNSUBACK with successful unsubscriptions
let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![
        UnsubackReasonCode::Success,
        UnsubackReasonCode::NoSubscriptionExisted,
    ])
    .build()
    .unwrap();

assert_eq!(unsuback.packet_id(), 42);
assert_eq!(unsuback.reason_codes().len(), 2);

// Create UNSUBACK with mixed success and error codes
let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(100u16)
    .reason_codes(vec![
        UnsubackReasonCode::Success,
        UnsubackReasonCode::NotAuthorized,
        UnsubackReasonCode::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 unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(200u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .props(props)
    .build()
    .unwrap();

// Serialize to bytes for network transmission
let buffers = unsuback.to_buffers();

Fields§

§props: Properties

MQTT 5.0 properties for the UNSUBACK 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> GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Source

pub fn props(&self) -> &Properties

MQTT 5.0 properties for the UNSUBACK packet

Contains optional properties like reason string and user properties. The properties are validated to ensure only allowed properties are included.

Source§

impl<PacketIdType> GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Source

pub fn builder() -> GenericUnsubackBuilder<PacketIdType>

Create a new GenericUnsubackBuilder for constructing UNSUBACK packets

Returns a builder instance that allows setting the various fields of an UNSUBACK packet in a fluent interface style. The builder ensures all required fields are set before creating the final packet.

§Returns

A new GenericUnsubackBuilder<PacketIdType> instance

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::GenericUnsuback::<u16>::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();
Source

pub fn packet_type() -> PacketType

Get the packet type for UNSUBACK packets

Returns the constant packet type identifier for UNSUBACK packets. This is always PacketType::Unsuback for UNSUBACK packets.

§Returns

The packet type PacketType::Unsuback

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::packet_type::PacketType;

assert_eq!(mqtt::packet::v5_0::Unsuback::packet_type(), PacketType::Unsuback);
Source

pub fn packet_id(&self) -> PacketIdType

Get the packet identifier from the UNSUBACK packet

Returns the packet identifier that matches the UNSUBSCRIBE packet this UNSUBACK is responding to. The packet identifier is used to correlate the UNSUBACK with the original UNSUBSCRIBE request.

§Returns

The packet identifier as PacketIdType

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(1234u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

assert_eq!(unsuback.packet_id(), 1234);
Source

pub fn reason_codes(&self) -> Vec<UnsubackReasonCode>

Get the reason codes from the UNSUBACK packet

Returns a vector of reason codes indicating the result of each unsubscription request in the original UNSUBSCRIBE packet. Each reason code corresponds to a topic filter in the UNSUBSCRIBE packet, in the same order.

Invalid reason code bytes are converted to UnsubackReasonCode::UnspecifiedError to maintain packet integrity.

§Returns

A Vec<UnsubackReasonCode> containing the unsubscription results

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::result_code::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![
        UnsubackReasonCode::Success,
        UnsubackReasonCode::NotAuthorized,
        UnsubackReasonCode::NoSubscriptionExisted,
    ])
    .build()
    .unwrap();

let codes = unsuback.reason_codes();
assert_eq!(codes.len(), 3);
assert_eq!(codes[0], UnsubackReasonCode::Success);
assert_eq!(codes[1], UnsubackReasonCode::NotAuthorized);
assert_eq!(codes[2], UnsubackReasonCode::NoSubscriptionExisted);
Source

pub fn parse(data: &[u8]) -> Result<(Self, usize), MqttError>

Parse an UNSUBACK packet from raw bytes

Parses the variable header and payload of an UNSUBACK packet from the provided byte buffer. The fixed header should already be parsed before calling this method.

§Arguments
  • data - The raw bytes containing the UNSUBACK packet variable header and payload
§Returns

Returns a tuple containing:

  • The parsed GenericUnsuback 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 UNSUBACK packet from network data
let data = &[0x00, 0x10, 0x00, 0x00]; // packet_id=16, no properties, success code
let (unsuback, consumed) = mqtt::packet::v5_0::Unsuback::parse(data).unwrap();

assert_eq!(unsuback.packet_id(), 16);
assert_eq!(consumed, 4);
Source

pub fn size(&self) -> usize

Calculate the total size of the UNSUBACK packet in bytes

Returns the total number of bytes required to represent this UNSUBACK 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

let size = unsuback.size();
assert!(size > 0);
Source

pub fn to_buffers(&self) -> Vec<IoSlice<'_>>

Convert the UNSUBACK 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 UNSUBACK packet in wire format.

The returned buffers contain the packet in the following order:

  1. Fixed header (packet type and remaining length)
  2. Packet identifier
  3. Property length
  4. Properties (if any)
  5. 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

let buffers = unsuback.to_buffers();
// Use buffers for vectored I/O operations
// let bytes_written = socket.write_vectored(&buffers)?;

Trait Implementations§

Source§

impl AsConcrete<GenericUnsuback<u16>> for Packet

Source§

impl<PacketIdType> Clone for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Clone, PacketIdType::Buffer: Clone,

Source§

fn clone(&self) -> GenericUnsuback<PacketIdType>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<PacketIdType> Debug for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Debug trait implementation for GenericUnsuback

Provides a debug representation of the UNSUBACK 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

println!("{:?}", unsuback); // Prints JSON representation
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<PacketIdType> Display for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Display trait implementation for GenericUnsuback

Provides a human-readable JSON representation of the UNSUBACK 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

println!("{}", unsuback); // Prints JSON representation
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<PacketIdType> From<GenericUnsuback<PacketIdType>> for GenericPacket<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Source§

fn from(v: GenericUnsuback<PacketIdType>) -> GenericPacket<PacketIdType>

Converts to this type from the input type.
Source§

impl<PacketIdType> GenericPacketDisplay for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

GenericPacketDisplay implementation for GenericUnsuback

Provides standardized display formatting for UNSUBACK 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

// Use trait methods for consistent formatting
println!("{}", format_args!("{}", unsuback));
Source§

fn fmt_debug(&self, f: &mut Formatter<'_>) -> Result

Source§

fn fmt_display(&self, f: &mut Formatter<'_>) -> Result

Source§

impl<PacketIdType> GenericPacketTrait for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

GenericPacketTrait implementation for GenericUnsuback

Provides the standard packet interface methods for UNSUBACK packets. This trait allows UNSUBACK 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

// Use trait methods
let size = unsuback.size();
let buffers = unsuback.to_buffers();
Source§

fn size(&self) -> usize

Source§

fn to_buffers(&self) -> Vec<IoSlice<'_>>

Source§

impl IntoConcreteOwned<GenericUnsuback<u16>> for Packet

Source§

impl<PacketIdType> PacketKind for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Source§

const IS_UNSUBACK: bool = true

true if this is an UNSUBACK packet
Source§

const IS_V5_0: bool = true

true if this is an MQTT v5.0 packet
Source§

const IS_CONNECT: bool = false

true if this is a CONNECT packet
Source§

const IS_CONNACK: bool = false

true if this is a CONNACK packet
Source§

const IS_PUBLISH: bool = false

true if this is a PUBLISH packet
Source§

const IS_PUBACK: bool = false

true if this is a PUBACK packet
Source§

const IS_PUBREC: bool = false

true if this is a PUBREC packet
Source§

const IS_PUBREL: bool = false

true if this is a PUBREL packet
Source§

const IS_PUBCOMP: bool = false

true if this is a PUBCOMP packet
Source§

const IS_SUBSCRIBE: bool = false

true if this is a SUBSCRIBE packet
Source§

const IS_SUBACK: bool = false

true if this is a SUBACK packet
Source§

const IS_UNSUBSCRIBE: bool = false

true if this is an UNSUBSCRIBE packet
Source§

const IS_PINGREQ: bool = false

true if this is a PINGREQ packet
Source§

const IS_PINGRESP: bool = false

true if this is a PINGRESP packet
Source§

const IS_DISCONNECT: bool = false

true if this is a DISCONNECT packet
Source§

const IS_AUTH: bool = false

true if this is an AUTH packet (v5.0 only)
Source§

const IS_V3_1_1: bool = false

true if this is an MQTT v3.1.1 packet
Source§

impl<PacketIdType> PartialEq for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + PartialEq, PacketIdType::Buffer: PartialEq,

Source§

fn eq(&self, other: &GenericUnsuback<PacketIdType>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<PacketIdType> Serialize for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Serialize trait implementation for GenericUnsuback

Provides JSON serialization support for UNSUBACK packets. The serialized format includes the packet type, packet ID, properties (if any), and reason codes.

The serialized structure contains:

  • type: Always “unsuback”
  • packet_id: The packet identifier
  • props: 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::UnsubackReasonCode;

let unsuback = mqtt::packet::v5_0::Unsuback::builder()
    .packet_id(42u16)
    .reason_codes(vec![UnsubackReasonCode::Success])
    .build()
    .unwrap();

let json = serde_json::to_string(&unsuback).unwrap();
// json contains: {"type":"unsuback","packet_id":42,"reason_codes":["Success"]}
Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<PacketIdType> TryInto<GenericUnsuback<PacketIdType>> for GenericPacket<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Source§

type Error = &'static str

The type returned in the event of a conversion error.
Source§

fn try_into( self, ) -> Result<GenericUnsuback<PacketIdType>, <Self as TryInto<GenericUnsuback<PacketIdType>>>::Error>

Performs the conversion.
Source§

impl<PacketIdType> Eq for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId + Eq, PacketIdType::Buffer: Eq,

Source§

impl<PacketIdType> SendableRole<Any> for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Source§

impl<PacketIdType> SendableRole<Server> for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Source§

impl<PacketIdType> StructuralPartialEq for GenericUnsuback<PacketIdType>
where PacketIdType: IsPacketId,

Auto Trait Implementations§

§

impl<PacketIdType> Freeze for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: Freeze,

§

impl<PacketIdType> RefUnwindSafe for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: RefUnwindSafe,

§

impl<PacketIdType> Send for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: Send,

§

impl<PacketIdType> Sync for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: Sync,

§

impl<PacketIdType> Unpin for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: Unpin,

§

impl<PacketIdType> UnwindSafe for GenericUnsuback<PacketIdType>
where <PacketIdType as IsPacketId>::Buffer: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsConcrete<T> for T

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoConcreteOwned<T> for T

Source§

impl<Role, PacketIdType, T> Sendable<Role, PacketIdType> for T
where Role: RoleType, PacketIdType: IsPacketId, T: SendableRole<Role> + SendableVersion + Display + Debug + PacketKind + SendableHelper<Role, PacketIdType>,

Source§

fn dispatch_send( self, connection: &mut GenericConnection<Role, PacketIdType>, ) -> Vec<GenericEvent<PacketIdType>>

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more