mqtt_protocol_core/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2
3//! # MQTT Protocol Core
4//!
5//! A Sans-I/O style MQTT protocol library for Rust that supports both MQTT v5.0 and v3.1.1.
6//!
7//! This library provides a pure protocol implementation without any I/O operations,
8//! making it suitable for use with any async runtime or synchronous I/O framework.
9//! All operations are synchronous and the library focuses solely on MQTT protocol
10//! message parsing, validation, and generation.
11//!
12//! ## Features
13//!
14//! - **Sans-I/O Design**: Pure protocol implementation with no I/O dependencies
15//! - **Dual Version Support**: Full support for both MQTT v3.1.1 and v5.0
16//! - **Generic Packet ID**: Supports custom packet ID types (u16, u32) for broker clustering
17//! - **Zero-Copy Payload**: Efficient payload handling with `ArcPayload`
18//! - **Comprehensive**: All MQTT packet types and features supported
19//! - **Type Safety**: Compile-time role and version checking
20//!
21//! ## Quick Start
22//!
23//! ### Basic Client Connection
24//!
25//! ```rust,no_run
26//! use mqtt_protocol_core::mqtt::{
27//! Connection, Version,
28//! connection::role::Client,
29//! packet::v5_0::Connect,
30//! };
31//!
32//! // Create a client connection for MQTT v5.0
33//! let mut client = Connection::<Client>::new(Version::V5_0);
34//!
35//! // Create a CONNECT packet
36//! let connect = Connect::builder()
37//! .client_id("my-client")
38//! .unwrap()
39//! .clean_start(true)
40//! .build()
41//! .unwrap();
42//!
43//! // Send the packet through the connection
44//! let events = client.send(connect.into());
45//! ```
46//!
47//! ### Server with Version Auto-Detection
48//!
49//! ```rust,no_run
50//! use mqtt_protocol_core::mqtt::{
51//! Connection, Version,
52//! connection::role::Server,
53//! };
54//!
55//! // Create a server that accepts any MQTT version
56//! let mut server = Connection::<Server>::new(Version::Undetermined);
57//!
58//! // The server will automatically adapt to the client's protocol version
59//! // when it receives a CONNECT packet
60//! ```
61//!
62//! ## Architecture
63//!
64//! The library is organized into several key modules:
65//!
66//! - [`mqtt::connection`] - Connection state management and packet processing
67//! - [`mqtt::packet`] - MQTT packet definitions for v3.1.1 and v5.0
68//! - [`mqtt::Version`] - Protocol version handling
69//! - [`mqtt::ArcPayload`] - Efficient payload management
70//!
71//! ## Sans-I/O Pattern
72//!
73//! This library follows the Sans-I/O pattern, meaning it handles protocol logic
74//! without performing any I/O operations. Instead, it returns events that tell
75//! your application what actions to take:
76//!
77//! ```rust,no_run
78//! use mqtt_protocol_core::mqtt::{
79//! Connection, Version,
80//! connection::{role::Client, event::GenericEvent},
81//! common::Cursor,
82//! };
83//!
84//! let mut client = Connection::<Client>::new(Version::V5_0);
85//! let data = &[0u8; 0][..];
86//! let mut data_cursor = Cursor::new(data);
87//! let events = client.recv(&mut data_cursor);
88//!
89//! for event in events {
90//! match event {
91//! GenericEvent::RequestSendPacket { packet, .. } => {
92//! // Send packet over network
93//! }
94//! GenericEvent::NotifyPacketReceived(packet) => {
95//! // Handle received packet
96//! }
97//! // ... other events
98//! _ => {}
99//! }
100//! }
101//! ```
102//!
103//! ## Generic Packet ID Support
104//!
105//! The library supports custom packet ID types for advanced use cases like
106//! broker clustering, where u32 packet IDs can prevent ID exhaustion:
107//!
108//! ```rust,no_run
109//! use mqtt_protocol_core::mqtt::{GenericConnection, connection::role::Server};
110//!
111//! // Use u32 packet IDs instead of standard u16
112//! let mut server = GenericConnection::<Server, u32>::new(
113//! mqtt_protocol_core::mqtt::Version::V5_0
114//! );
115//! ```
116//!
117//! ## No-std Support
118//!
119//! This library fully supports `no_std` environments for embedded systems.
120//! To use in a `no_std` environment, disable the default `std` feature:
121//!
122//! ```toml
123//! [dependencies]
124//! mqtt-protocol-core = { version = "0.4.0", default-features = false }
125//! ```
126//!
127//! **No-std usage example:**
128//!
129//! ```rust,no_run,ignore
130//! #![no_std]
131//! extern crate alloc;
132//!
133//! use alloc::{vec::Vec, string::String};
134//! use mqtt_protocol_core::mqtt::{
135//! Connection, Version,
136//! connection::role::Client,
137//! packet::v5_0::Connect,
138//! common::Cursor,
139//! };
140//!
141//! fn main() {
142//! // Create client connection
143//! let mut client = Connection::<Client>::new(Version::V5_0);
144//!
145//! // Create CONNECT packet
146//! let connect = Connect::builder()
147//! .client_id("embedded-client")
148//! .unwrap()
149//! .clean_start(true)
150//! .build()
151//! .unwrap();
152//!
153//! // Send packet and handle events
154//! let events = client.send(connect.into());
155//!
156//! // Process events in your embedded application
157//! for event in events {
158//! match event {
159//! // Handle RequestSendPacket, NotifyPacketReceived, etc.
160//! _ => {}
161//! }
162//! }
163//! }
164//! ```
165//!
166//! ## Optional Features
167//!
168//! The library supports several optional features:
169//!
170//! - **`std`** (default): Enables standard library support, including `std::io::IoSlice` for vectored I/O
171//! - **`tracing`**: Enables logging support via the `tracing` crate. When disabled, trace statements compile to no-ops with zero overhead
172//!
173//! ```toml
174//! # Enable tracing support (independent of std)
175//! [dependencies]
176//! mqtt-protocol-core = { version = "0.4.0", default-features = false, features = ["tracing"] }
177//!
178//! # Use with std but without tracing overhead
179//! [dependencies]
180//! mqtt-protocol-core = { version = "0.4.0", default-features = false, features = ["std"] }
181//!
182//! # Full-featured (std + tracing)
183//! [dependencies]
184//! mqtt-protocol-core = { version = "0.4.0", features = ["tracing"] }
185//! ```
186//!
187//! **Key points for no-std usage:**
188//! - Use `extern crate alloc;` to enable heap allocations
189//! - Import types from `alloc` crate instead of `std`
190//! - `IoSlice` functionality is not available in `no_std` mode
191//! - Tracing can be enabled independently of `std` for embedded debugging
192
193// MIT License
194//
195// Copyright (c) 2025 Takatoshi Kondo
196//
197// Permission is hereby granted, free of charge, to any person obtaining a copy
198// of this software and associated documentation files (the "Software"), to deal
199// in the Software without restriction, including without limitation the rights
200// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
201// copies of the Software, and to permit persons to whom the Software is
202// furnished to do so, subject to the following conditions:
203//
204// The above copyright notice and this permission notice shall be included in all
205// copies or substantial portions of the Software.
206//
207// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
208// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
209// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
210// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
212// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
213// SOFTWARE.
214
215// Always use alloc types for consistency between std and no-std
216#[macro_use]
217extern crate alloc;
218
219// Common prelude with alloc types
220pub mod prelude {
221 pub use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
222
223 #[cfg(feature = "std")]
224 pub use std::io::IoSlice;
225}
226
227pub mod mqtt;