Struct GenericPubrec

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

A PUBREC packet for MQTT v5.0 protocol.

The PUBREC packet is the response to a PUBLISH packet with QoS level 2 and is the second step in the four-part handshake for QoS 2 message delivery. The complete QoS 2 flow is:

  1. PUBLISH (sender -> receiver)
  2. PUBREC (receiver -> sender) - this packet
  3. PUBREL (sender -> receiver)
  4. PUBCOMP (receiver -> sender)

§MQTT v5.0 Specification

According to the MQTT v5.0 specification, the PUBREC packet:

  • Is sent by the receiver of a PUBLISH packet with QoS 2
  • Contains the same Packet Identifier as the PUBLISH packet being acknowledged
  • Indicates that the message has been received but not yet processed
  • May optionally include a reason code indicating the result of the message reception
  • May optionally include properties for additional metadata
  • Must be followed by a PUBREL packet from the original sender

§QoS 2 Message Flow

The PUBREC packet ensures exactly-once delivery semantics:

  • Upon receiving a QoS 2 PUBLISH, the receiver stores the message and sends PUBREC
  • The PUBREC acknowledges message receipt and requests the sender to proceed
  • The sender must respond with PUBREL to confirm message processing should continue
  • Only after receiving PUBREL does the receiver process the message and send PUBCOMP

§Reason Codes

PUBREC packets can include reason codes to indicate the result of message processing:

  • Success (0x00): Message received successfully
  • NoMatchingSubscribers (0x10): No subscribers matched the topic
  • UnspecifiedError (0x80): An unspecified error occurred
  • ImplementationSpecificError (0x83): Implementation-specific error
  • NotAuthorized (0x87): Client not authorized to publish to this topic
  • TopicNameInvalid (0x90): Topic name format is invalid
  • PacketIdentifierInUse (0x91): Packet identifier already in use
  • QuotaExceeded (0x97): Quota exceeded
  • PayloadFormatInvalid (0x99): Payload format does not match the format indicator

§Generic Support

This struct supports generic packet identifiers through the PacketIdType parameter, allowing for extended packet ID ranges (e.g., u32) for broker clustering scenarios. The standard type alias Pubrec uses u16 packet identifiers as per MQTT specification.

§Examples

Creating a basic PUBREC packet:

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

assert_eq!(pubrec.packet_id(), 123u16);
assert_eq!(pubrec.reason_code(), None);

Creating a PUBREC with reason code:

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(456u16)
    .reason_code(mqtt::result_code::PubrecReasonCode::Success)
    .build()
    .unwrap();

assert_eq!(pubrec.packet_id(), 456u16);
assert_eq!(pubrec.reason_code(), Some(mqtt::result_code::PubrecReasonCode::Success));

Creating a PUBREC with properties:

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let properties = vec![
    mqtt::packet::Property::ReasonString("Message received".to_string()),
    mqtt::packet::Property::UserProperty(("key".to_string(), "value".to_string())),
];

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(789u16)
    .reason_code(mqtt::result_code::PubrecReasonCode::Success)
    .props(properties)
    .build()
    .unwrap();

assert_eq!(pubrec.packet_id(), 789u16);
assert!(pubrec.props().is_some());

Fields§

§props: Option<Properties>

Optional MQTT v5.0 properties associated with this PUBREC packet.

Properties can include:

  • ReasonString: Human readable string designed for diagnostics
  • UserProperty: Name-value pairs for application-specific metadata

Only one ReasonString property is allowed per packet. Properties can only be included if a reason code is also present.

Implementations§

Source§

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

Source

pub fn props(&self) -> &Option<Properties>

Optional MQTT v5.0 properties associated with this PUBREC packet.

Properties can include:

  • ReasonString: Human readable string designed for diagnostics
  • UserProperty: Name-value pairs for application-specific metadata

Only one ReasonString property is allowed per packet. Properties can only be included if a reason code is also present.

Source§

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

Source

pub fn builder() -> GenericPubrecBuilder<PacketIdType>

Creates a new builder for constructing a PUBREC packet.

§Returns

A new GenericPubrecBuilder instance for building a PUBREC packet.

§Examples
use mqtt_protocol_core::mqtt;

let builder = mqtt::packet::v5_0::Pubrec::builder();
let pubrec = builder
    .packet_id(42u16)
    .build()
    .unwrap();
Source

pub fn packet_type() -> PacketType

Returns the packet type for PUBREC packets.

§Returns

Always returns PacketType::Pubrec.

§Examples
use mqtt_protocol_core::mqtt;

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

pub fn packet_id(&self) -> PacketIdType

Returns the packet identifier for this PUBREC packet.

The packet identifier must match the packet identifier of the PUBLISH packet being acknowledged. It is used to correlate the PUBREC with the original PUBLISH in the QoS 2 message flow.

§Returns

The packet identifier as the generic PacketIdType.

§Examples
use mqtt_protocol_core::mqtt;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

assert_eq!(pubrec.packet_id(), 123u16);
Source

pub fn reason_code(&self) -> Option<PubrecReasonCode>

Returns the reason code for this PUBREC packet, if present.

The reason code indicates the result of the PUBLISH message processing. If no reason code is present, it is assumed to be Success (0x00).

§Returns
  • Some(PubrecReasonCode) if a reason code was included in the packet
  • None if no reason code was present (implies success)
§Examples
use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

// PUBREC without reason code (implies success)
let pubrec1 = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();
assert_eq!(pubrec1.reason_code(), None);

// PUBREC with explicit reason code
let pubrec2 = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(456u16)
    .reason_code(mqtt::result_code::PubrecReasonCode::NoMatchingSubscribers)
    .build()
    .unwrap();
assert_eq!(pubrec2.reason_code(), Some(mqtt::result_code::PubrecReasonCode::NoMatchingSubscribers));
Source

pub fn size(&self) -> usize

Returns the total size of this PUBREC packet in bytes.

This includes the fixed header, remaining length field, and all variable header and payload components.

§Returns

The total packet size in bytes.

§Examples
use mqtt_protocol_core::mqtt;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

let size = pubrec.size();
// Size includes: fixed header (1) + remaining length (1) + packet_id (2) = 4 bytes minimum
assert!(size >= 4);
Source

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

Converts this PUBREC packet into a vector of I/O slices for efficient writing.

This method provides zero-copy serialization by returning references to the internal packet data as IoSlice objects, which can be used with vectored I/O operations.

§Returns

A vector of IoSlice objects representing the complete packet data.

§Examples
use mqtt_protocol_core::mqtt;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

let buffers = pubrec.to_buffers();
// Use buffers for vectored I/O operations
Source

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

Parses a PUBREC packet from raw byte data.

This method parses the variable header and properties of a PUBREC packet from the provided byte slice. The fixed header should have already been parsed and removed from the data.

§Parameters
  • data - The raw packet data excluding the fixed header
§Returns
  • Ok((GenericPubrec, usize)) - The parsed PUBREC packet and number of bytes consumed
  • Err(MqttError) - If the packet data is malformed or invalid
§Errors

Returns MqttError::MalformedPacket if:

  • The packet identifier is zero (invalid per MQTT specification)
  • The reason code is invalid
  • The packet structure is malformed

Returns MqttError::ProtocolError if:

  • Invalid properties are present
  • Multiple ReasonString properties are included
§Examples
use mqtt_protocol_core::mqtt;

// Assume `packet_data` contains valid PUBREC packet bytes
let packet_data = &[0x00, 0x01]; // packet_id = 1
let (pubrec, consumed) = mqtt::packet::v5_0::Pubrec::parse(packet_data).unwrap();
assert_eq!(pubrec.packet_id(), 1u16);
assert_eq!(consumed, 2);

Trait Implementations§

Source§

impl AsConcrete<GenericPubrec<u16>> for Packet

Source§

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

Source§

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

Implementation of Debug trait for PUBREC packet debugging.

This implementation delegates to the Display implementation to provide consistent formatting for debug output. The JSON format makes it easy to inspect packet contents during development and debugging.

§Examples

use mqtt_protocol_core::mqtt;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

println!("{:?}", pubrec);
// Output: {"type":"pubrec","packet_id":123}
Source§

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

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

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

Implementation of Display trait for human-readable PUBREC packet representation.

This implementation formats the PUBREC packet as a JSON string for easy reading and debugging. It leverages the Serialize implementation to generate consistent output across different display contexts.

§Output Format

The output is a JSON object containing all relevant packet information:

  • Packet type and identifier
  • Reason code (if present)
  • Properties (if present)

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(42u16)
    .reason_code(mqtt::result_code::PubrecReasonCode::Success)
    .build()
    .unwrap();

println!("{}", pubrec);
// Output: {"type":"pubrec","packet_id":42,"reason_code":"Success"}
Source§

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

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

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

Source§

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

Converts to this type from the input type.
Source§

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

Implementation of GenericPacketDisplay for PUBREC packets.

This trait provides consistent display and debug formatting for PUBREC packets when used in generic packet contexts. It delegates to the standard Display and Debug trait implementations.

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

// Use in generic packet display contexts
println!("{}", pubrec); // Uses fmt_display
println!("{:?}", pubrec); // Uses fmt_debug
Source§

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

Source§

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

Source§

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

Implementation of GenericPacketTrait for PUBREC packets.

This trait provides common packet functionality such as size calculation and buffer serialization. It allows PUBREC packets to be treated uniformly with other MQTT packet types in generic contexts.

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .build()
    .unwrap();

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

fn size(&self) -> usize

Source§

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

Source§

impl IntoConcreteOwned<GenericPubrec<u16>> for Packet

Source§

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

Source§

const IS_PUBREC: bool = true

true if this is a PUBREC 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_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_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 GenericPubrec<PacketIdType>
where PacketIdType: IsPacketId + PartialEq, PacketIdType::Buffer: PartialEq,

Source§

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

Implementation of Serialize trait for JSON serialization of PUBREC packets.

This implementation serializes a PUBREC packet into a JSON object containing the packet type, packet identifier, optional reason code, and optional properties. The serialization format is suitable for debugging, logging, and API responses.

§Serialized Fields

  • type: Always “pubrec” (string)
  • packet_id: The packet identifier (number)
  • reason_code: The reason code (optional, only if present)
  • props: The properties (optional, only if present)

§Examples

use mqtt_protocol_core::mqtt;
use mqtt_protocol_core::mqtt::prelude::*;

let pubrec = mqtt::packet::v5_0::Pubrec::builder()
    .packet_id(123u16)
    .reason_code(mqtt::result_code::PubrecReasonCode::Success)
    .build()
    .unwrap();

let json = serde_json::to_string(&pubrec).unwrap();
// JSON: {"type":"pubrec","packet_id":123,"reason_code":"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<GenericPubrec<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<GenericPubrec<PacketIdType>, <Self as TryInto<GenericPubrec<PacketIdType>>>::Error>

Performs the conversion.
Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

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

§

impl<PacketIdType> UnwindSafe for GenericPubrec<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