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.7.1", 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//! ## Feature Flags
167//!
168//! ### Core 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.7.1", default-features = false, features = ["tracing"] }
177//!
178//! # Use with std but without tracing overhead
179//! [dependencies]
180//! mqtt-protocol-core = { version = "0.7.1", default-features = false, features = ["std"] }
181//!
182//! # Full-featured (std + tracing)
183//! [dependencies]
184//! mqtt-protocol-core = { version = "0.7.1", features = ["tracing"] }
185//! ```
186//!
187//! ### Small String Optimization (SSO) Features
188//!
189//! These features optimize memory usage for small strings and binary data by storing them
190//! on the stack instead of allocating on the heap:
191//!
192//! - **`sso-min-32bit`**: Minimal optimization for 32-bit environments
193//! - MqttString/MqttBinary: 12 bytes total buffer
194//! - ArcPayload: 15 bytes data buffer
195//!
196//! - **`sso-min-64bit`**: Recommended optimization for 64-bit environments
197//! - MqttString/MqttBinary: 24 bytes total buffer
198//! - ArcPayload: 31 bytes data buffer
199//!
200//! - **`sso-lv10`**: Level 10 optimization for moderate performance gains
201//! - MqttString/MqttBinary: 24 bytes total buffer
202//! - ArcPayload: 127 bytes data buffer
203//!
204//! - **`sso-lv20`**: Level 20 optimization for maximum performance
205//! - MqttString/MqttBinary: 48 bytes total buffer
206//! - ArcPayload: 255 bytes data buffer
207//!
208//! ```toml
209//! # Use specific SSO optimization level
210//! [dependencies]
211//! mqtt-protocol-core = { version = "0.7.1", features = ["sso-lv10"] }
212//!
213//! # Combine with other features
214//! [dependencies]
215//! mqtt-protocol-core = { version = "0.7.1", features = ["std", "sso-lv20", "tracing"] }
216//! ```
217//!
218//! #### ⚠️ **Critical: SSO Feature Flag Propagation**
219//!
220//! **When your crate depends on mqtt-protocol-core and is consumed by other crates,
221//! you should re-export all SSO feature flags to ensure proper feature selection.**
222//!
223//! **Multiple SSO Features:** When multiple SSO features are enabled simultaneously,
224//! the system automatically selects the **largest buffer size** from the enabled features.
225//! This allows safe usage with `--all-features` and prevents compilation errors.
226//!
227//! **Feature Selection Priority:**
228//! 1. `sso-lv20` (highest): 48-byte String/Binary, 255-byte ArcPayload
229//! 2. `sso-lv10` or `sso-min-64bit`: 24-byte String/Binary, 127-byte ArcPayload
230//! 3. `sso-min-32bit` (lowest): 12-byte String/Binary, 15-byte ArcPayload
231//!
232//! **Required pattern for library authors:**
233//!
234//! ```toml
235//! # Your crate's Cargo.toml
236//! [dependencies]
237//! mqtt-protocol-core = { version = "0.7.1", features = ["sso-lv10"] }
238//!
239//! [features]
240//! # MANDATORY: Re-export ALL SSO features to allow downstream configuration
241//! sso-min-32bit = ["mqtt-protocol-core/sso-min-32bit"]
242//! sso-min-64bit = ["mqtt-protocol-core/sso-min-64bit"]
243//! sso-lv10 = ["mqtt-protocol-core/sso-lv10"]
244//! sso-lv20 = ["mqtt-protocol-core/sso-lv20"]
245//! ```
246//!
247//! This pattern ensures that when multiple dependency crates enable different SSO levels,
248//! the final application receives the maximum optimization level from all dependencies.
249//!
250//! **Key points for no-std usage:**
251//! - Use `extern crate alloc;` to enable heap allocations
252//! - Import types from `alloc` crate instead of `std`
253//! - `IoSlice` functionality is not available in `no_std` mode
254//! - Tracing can be enabled independently of `std` for embedded debugging
255
256// MIT License
257//
258// Copyright (c) 2025 Takatoshi Kondo
259//
260// Permission is hereby granted, free of charge, to any person obtaining a copy
261// of this software and associated documentation files (the "Software"), to deal
262// in the Software without restriction, including without limitation the rights
263// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
264// copies of the Software, and to permit persons to whom the Software is
265// furnished to do so, subject to the following conditions:
266//
267// The above copyright notice and this permission notice shall be included in all
268// copies or substantial portions of the Software.
269//
270// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
271// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
272// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
273// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
274// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
275// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
276// SOFTWARE.
277
278// Always use alloc types for consistency between std and no-std
279#[macro_use]
280extern crate alloc;
281
282// Common prelude with alloc types
283pub mod prelude {
284 pub use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
285
286 #[cfg(feature = "std")]
287 pub use std::io::IoSlice;
288}
289
290pub mod mqtt;