GenericSubscribe

Struct GenericSubscribe 

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

MQTT 5.0 SUBSCRIBE packet representation

The SUBSCRIBE packet is sent by a client to subscribe to one or more topic filters on the server. Each subscription establishes a flow of messages from the server to the client based on the matching topic filters and their associated subscription options.

According to MQTT 5.0 specification, the SUBSCRIBE packet contains:

  • Fixed header with packet type (bit 7-4 = 1000), reserved flags (bit 3-0 = 0010), and remaining length
  • Variable header with packet identifier and properties
  • Payload containing one or more topic filter entries with subscription options

§Fixed Header

The SUBSCRIBE packet uses a fixed header with:

  • Packet Type: 8 (1000 binary) in bits 7-4 of the first byte
  • Reserved Flags: 2 (0010 binary) in bits 3-0 - these flags are reserved and must be set as shown
  • Remaining Length: Variable length encoding of the remaining packet data

§Variable Header

The variable header contains:

  • Packet Identifier: A 16-bit identifier used to match SUBSCRIBE with SUBACK packets
  • Properties: MQTT 5.0 properties that modify the behavior of the subscription

§Payload

The payload contains one or more subscription entries, each consisting of:

  • Topic Filter: UTF-8 encoded string that may contain wildcards (+ and #)
  • Subscription Options: Byte containing QoS, No Local, Retain As Published, and Retain Handling flags

§Quality of Service (QoS)

Each subscription specifies a maximum QoS level:

  • QoS 0: At most once delivery
  • QoS 1: At least once delivery
  • QoS 2: Exactly once delivery

§Topic Filters and Wildcards

Topic filters can include wildcards:

  • Single-level wildcard (+): Matches exactly one topic level (e.g., “sport/+/player1”)
  • Multi-level wildcard (#): Matches any number of topic levels (e.g., “sport/#”)

§MQTT 5.0 Subscription Options

  • No Local: If set, messages published by this client are not sent back to it
  • Retain As Published: If set, retain flag is preserved when forwarding messages
  • Retain Handling: Controls how retained messages are sent when subscription is established

§Properties

MQTT 5.0 SUBSCRIBE packets can include:

  • Subscription Identifier: Numeric identifier to associate with the subscription
  • User Properties: Custom key-value pairs for application-specific data

§Generic Type Parameter

The PacketIdType generic parameter allows using packet identifiers larger than the standard u16, which can be useful for broker clusters to avoid packet ID exhaustion when extending the MQTT protocol.

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

// Create a simple SUBSCRIBE packet for a single topic
let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(42)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("sensors/temperature")
            .unwrap()
            .qos(Qos::AtLeastOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

assert_eq!(subscribe.packet_id(), 42);
assert_eq!(subscribe.entries().len(), 1);
assert_eq!(subscribe.entries()[0].topic_filter(), "sensors/temperature");

// Create a SUBSCRIBE packet with multiple topics and properties
let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(123)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("home/+/temperature")
            .unwrap()
            .qos(Qos::AtMostOnce)
            .build()
            .unwrap(),
        SubEntry::builder()
            .topic_filter("alerts/#")
            .unwrap()
            .qos(Qos::ExactlyOnce)
            .no_local(true)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

assert_eq!(subscribe.packet_id(), 123);
assert_eq!(subscribe.entries().len(), 2);

// Serialize to bytes for network transmission
let buffers = subscribe.to_buffers();
let total_size = subscribe.size();

Fields§

§props: Properties

Implementations§

Source§

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

Source

pub fn props(&self) -> &Properties

Source

pub fn entries(&self) -> &Vec<SubEntry>

Source§

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

Source

pub fn builder() -> GenericSubscribeBuilder<PacketIdType>

Creates a new builder for constructing a SUBSCRIBE packet

The builder pattern allows for flexible construction of SUBSCRIBE packets with various combinations of properties, topic filters, and subscription options. All SUBSCRIBE packets must have a packet identifier and at least one subscription entry.

§Returns

A GenericSubscribeBuilder instance with default values

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(42)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("sensors/+")
            .unwrap()
            .qos(Qos::AtLeastOnce)
            .no_local(true)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();
Source

pub fn packet_type() -> PacketType

Returns the packet type for SUBSCRIBE packets

This is always PacketType::Subscribe for SUBSCRIBE packet instances. The numeric value is 8, represented as 1000 in the upper 4 bits of the fixed header’s first byte.

§Returns

PacketType::Subscribe

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

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

pub fn packet_id(&self) -> PacketIdType

Returns the packet identifier for this SUBSCRIBE packet

The packet identifier is used to match SUBSCRIBE packets with their corresponding SUBACK responses. It must be non-zero as specified in the MQTT protocol. The same packet identifier should not be reused until the SUBACK is received.

§Returns

The packet identifier as PacketIdType

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(123)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("test/topic")
            .unwrap()
            .qos(Qos::AtMostOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

assert_eq!(subscribe.packet_id(), 123);
Source

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

Parses a SUBSCRIBE packet from a byte buffer

This method parses the variable header and payload of a SUBSCRIBE packet, extracting the packet identifier, properties, and subscription entries. The fixed header should be parsed separately before calling this method.

§Parameters
  • data - Byte buffer containing the SUBSCRIBE packet data (without fixed header)
§Returns
  • Ok((GenericSubscribe, usize)) - The parsed SUBSCRIBE packet and number of bytes consumed
  • Err(MqttError) - If the packet is malformed or contains invalid data
§Errors
  • MqttError::MalformedPacket - If the packet structure is invalid
  • MqttError::ProtocolError - If the packet violates MQTT protocol rules (e.g., no entries)
§Examples
use mqtt_protocol_core::mqtt;

// This would typically be called by a packet parser after reading the fixed header
let data = &[0x00, 0x01, 0x00, 0x00, 0x09, b't', b'e', b's', b't', b'/', b't', b'o', b'p', b'i', b'c', 0x01];
let (subscribe, consumed) = mqtt::packet::v5_0::Subscribe::parse(data).unwrap();
assert_eq!(subscribe.packet_id(), 1);
assert_eq!(consumed, data.len());
Source

pub fn size(&self) -> usize

Returns the total size of the SUBSCRIBE packet in bytes

This includes the fixed header (1 byte for packet type + remaining length encoding) plus all variable header and payload data. This size can be used for buffer allocation before serialization.

§Returns

Total packet size in bytes

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(1)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("test")
            .unwrap()
            .qos(Qos::AtMostOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

let total_size = subscribe.size();
// Size includes: fixed header + packet_id + properties_length + properties + entries
Source

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

Create IoSlice buffers for efficient network I/O

Returns a vector of IoSlice objects that can be used for vectored I/O operations, allowing zero-copy writes to network sockets. The buffers represent the complete SUBSCRIBE packet in wire format.

§Returns

A vector of IoSlice objects for vectored I/O operations

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::SubEntry;
use mqtt_protocol_core::mqtt::qos::QoS;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(1u16)
    .entries(vec![
        SubEntry::new("test/topic", QoS::AtLeastOnce),
        SubEntry::new("another/topic", QoS::ExactlyOnce),
    ])
    .build()
    .unwrap();

let buffers = subscribe.to_buffers();
// Use with vectored write: socket.write_vectored(&buffers)?;
Source

pub fn to_continuous_buffer(&self) -> Vec<u8>

Create a continuous buffer containing the complete packet data

Returns a vector containing all packet bytes in a single continuous buffer. This method provides an alternative to to_buffers() for no-std environments where vectored I/O is not available.

The returned buffer contains the complete SUBSCRIBE packet serialized according to the MQTT v5.0 protocol specification, including fixed header, remaining length, packet identifier, properties, and subscription entries.

§Returns

A vector containing the complete packet data

§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::SubEntry;
use mqtt_protocol_core::mqtt::qos::QoS;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(1u16)
    .entries(vec![
        SubEntry::new("test/topic", QoS::AtLeastOnce),
    ])
    .build()
    .unwrap();

let buffer = subscribe.to_continuous_buffer();
// buffer contains all packet bytes

Trait Implementations§

Source§

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

Source§

fn clone(&self) -> GenericSubscribe<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 GenericSubscribe<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Debug trait implementation for SUBSCRIBE packets

Provides the same output as the Display trait, showing a JSON representation of the packet contents. This is consistent with other packet types in the library.

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(1)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("debug/topic")
            .unwrap()
            .qos(Qos::AtMostOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

println!("{:?}", subscribe);
Source§

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

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

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

Display trait implementation for SUBSCRIBE packets

Provides a human-readable JSON representation of the SUBSCRIBE packet, including the packet type, packet identifier, properties, and subscription entries. This is useful for debugging and logging purposes.

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(42)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("test/topic")
            .unwrap()
            .qos(Qos::AtLeastOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

println!("{}", subscribe);
// Output: {"type":"subscribe","packet_id":42,"entries":[...]}
Source§

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

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

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

Source§

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

Converts to this type from the input type.
Source§

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

Generic packet display trait implementation for SUBSCRIBE packets

Provides unified display formatting for packet types, supporting both debug and display formatting through a common interface. This is used by the packet handling infrastructure for consistent logging and debugging.

Source§

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

Source§

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

Source§

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

Generic packet trait implementation for SUBSCRIBE packets

Provides the common packet interface used by the MQTT protocol handler. This allows SUBSCRIBE packets to be treated uniformly with other packet types for size calculation and serialization operations.

§Methods

  • size(): Returns the total packet size in bytes
  • to_buffers(): Returns I/O slices for efficient transmission
Source§

fn size(&self) -> usize

Source§

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

Source§

fn to_continuous_buffer(&self) -> Vec<u8>

Create a continuous buffer containing the complete packet data Read more
Source§

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

Source§

const IS_SUBSCRIBE: bool = true

true if this is a SUBSCRIBE 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_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_UNSUBACK: bool = false

true if this is an UNSUBACK 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 GenericSubscribe<PacketIdType>
where PacketIdType: IsPacketId + PartialEq, PacketIdType::Buffer: PartialEq,

Source§

fn eq(&self, other: &GenericSubscribe<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 GenericSubscribe<PacketIdType>
where PacketIdType: IsPacketId + Serialize,

Serde Serialize trait implementation for SUBSCRIBE packets

Serializes the SUBSCRIBE packet to a structured format (typically JSON) containing the packet type, packet identifier, properties (if any), and subscription entries (if any). Empty collections are omitted from the output.

§Serialized Fields

  • type: Always “subscribe”
  • packet_id: The packet identifier
  • props: Properties object (only if non-empty)
  • entries: Array of subscription entries (only if non-empty)

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::packet::qos::Qos;
use mqtt_protocol_core::mqtt::packet::SubEntry;

let subscribe = mqtt::packet::v5_0::Subscribe::builder()
    .packet_id(123)
    .entries(vec![
        SubEntry::builder()
            .topic_filter("home/sensor")
            .unwrap()
            .qos(Qos::ExactlyOnce)
            .build()
            .unwrap()
    ])
    .build()
    .unwrap();

let json = serde_json::to_string(&subscribe).unwrap();
// json contains: {"type":"subscribe","packet_id":123,"entries":[...]}
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<GenericSubscribe<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<GenericSubscribe<PacketIdType>, <Self as TryInto<GenericSubscribe<PacketIdType>>>::Error>

Performs the conversion.
Source§

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

Source§

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

Source§

impl<PacketIdType> SendableRole<Client> for GenericSubscribe<PacketIdType>
where PacketIdType: IsPacketId,

Source§

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

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

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

§

impl<PacketIdType> UnwindSafe for GenericSubscribe<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> 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, 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<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.