flowsdk 0.5.1

Safety-first, realistic, behavior-predictable messaging SDK for MQTT and more.
Documentation
# Protocol Compliance Features

This document describes the protocol compliance features implemented in the MQTT library with configurable strict validation.

## Feature Flag: `strict-protocol-compliance`

The library includes a feature flag `strict-protocol-compliance` that enables additional MQTT 5.0 protocol compliance validations. This feature is **enabled by default** but can be disabled if needed.

### Enabling/Disabling the Feature

```toml
# In Cargo.toml - enable by default (current behavior)
[features]
default = ["strict-protocol-compliance"]
strict-protocol-compliance = []

# To disable strict compliance
cargo build --no-default-features
cargo test --no-default-features
```

## Implemented Validations

### General Validations

#### UTF-8 String Validation
When `strict-protocol-compliance` is enabled, all UTF-8 strings are validated to ensure they comply with MQTT 5.0 specification:

- **Null characters (U+0000)** are rejected
- **UTF-16 surrogate pairs (U+D800-U+DFFF)** are rejected  
- **BOM (Byte Order Mark, U+FEFF)** at the beginning of strings is rejected

**Error Messages:**
- `"UTF-8 string contains null character (U+0000)"`
- `"UTF-8 string contains surrogate character (U+XXXX)"`
- `"UTF-8 string starts with BOM (U+FEFF)"`

#### Variable Byte Integer (VBI) Validation
Non-minimal VBI encodings are detected and rejected. A VBI is considered non-minimal if it uses more bytes than necessary to represent a value.

**Error Message:**
- `"Variable Byte Integer encoding is not minimal"`

### CONNECT Packet Validation

#### Reserved Flag Validation
The reserved flag in Connect Flags must be 0.

**Error Message:**
- `"CONNECT packet reserved flag is not 0"`

#### Will Flag Validation
When Will Flag is not set (0):
- Will QoS must be 0
- Will Retain must be 0

When Will Flag is set:
- Will QoS cannot be 3 (invalid/malformed packet)

**Error Messages:**
- `"Will QoS must be 0 if Will Flag is 0"`
- `"Will Retain must be 0 if Will Flag is 0"`
- `"Will QoS cannot be 3"`

### CONNACK Packet Validation

#### Reserved Bits Validation
The Connect Acknowledge Flags byte must have all reserved bits set to 0.

**Error Message:**
- `"CONNACK Connect Acknowledge Flags reserved bits must be 0"`

### PUBLISH Packet Validation

#### QoS Validation
- QoS level 3 (`11` in binary) is invalid and rejected
- DUP flag must be 0 for QoS 0 messages

**Error Messages:**
- `"PUBLISH QoS bits must not be set to 11 (invalid QoS 3)"`
- `"PUBLISH DUP flag must be 0 for QoS 0 messages"`

#### Topic Name Validation
Topic names in PUBLISH packets must not contain wildcard characters (`#` or `+`).

**Error Message:**
- `"PUBLISH Topic Name must not contain wildcard characters (# or +)"`

### SUBSCRIBE Packet Validation

#### Fixed Header Flags
SUBSCRIBE packets must have fixed header flags set to `0010` (bit 1 = 1, others = 0).

**Error Message:**
- `"SUBSCRIBE fixed header flags must be 0010"`

#### Packet Identifier Validation
Packet identifier must be greater than 0.

**Error Message:**
- `"SUBSCRIBE packet_id must be > 0"`

#### Payload Validation
The payload must contain at least one subscription.

**Error Message:**
- `"SUBSCRIBE payload must contain at least one subscription"`

#### Subscription Options Validation
Reserved bits in Subscription Options must be 0.

**Error Message:**
- `"SUBSCRIBE Subscription Options reserved bits must be 0"`

#### No Local Flag Validation
The No Local flag cannot be set on shared subscriptions (topics starting with `$share/`).

**Error Message:**
- `"SUBSCRIBE No Local flag must not be set on Shared Subscriptions"`

#### Topic Filter Validation
Comprehensive validation of topic filter syntax including:

- Empty topic filters are rejected
- Multi-level wildcards (`#`) must be the only character in the level and the last level
- Single-level wildcards (`+`) must be the only character in the level
- Maximum length validation (65535 bytes)

**Error Messages:**
- `"Topic filter cannot be empty"`
- `"Multi-level wildcard (#) must be the only character in topic level"`
- `"Multi-level wildcard (#) must be the last level in topic filter"`
- `"Single-level wildcard (+) must be the only character in topic level"`

#### Shared Subscription Validation
Shared subscriptions must follow the format `$share/ShareName/TopicFilter`:

- ShareName cannot be empty
- TopicFilter cannot be empty
- The TopicFilter part is validated according to normal topic filter rules

**Error Messages:**
- `"Invalid shared subscription format: must be $share/ShareName/TopicFilter"`
- `"Shared subscription ShareName cannot be empty"`
- `"Shared subscription TopicFilter cannot be empty"`

### SUBACK Packet Validation

#### Packet Identifier Validation
Packet identifier must be greater than 0.

**Error Message:**
- `"SUBACK packet_id must be > 0"`

#### Payload Validation
The payload must contain at least one reason code.

**Error Message:**
- `"SUBACK payload must contain at least one reason code"`

### UNSUBSCRIBE Packet Validation

#### Fixed Header Flags
UNSUBSCRIBE packets must have fixed header flags set to `0010` (bit 1 = 1, others = 0).

**Error Message:**
- `"UNSUBSCRIBE fixed header flags must be 0010"`

#### Packet Identifier Validation
Packet identifier must be greater than 0.

**Error Message:**
- `"UNSUBSCRIBE packet_id must be > 0"`

#### Payload Validation
The payload must contain at least one topic filter.

**Error Message:**
- `"UNSUBSCRIBE payload must contain at least one topic filter"`

### UNSUBACK Packet Validation

#### Packet Identifier Validation
Packet identifier must be greater than 0.

**Error Message:**
- `"UNSUBACK packet_id must be > 0"`

#### Payload Validation
The payload must contain at least one reason code.

**Error Message:**
- `"UNSUBACK payload must contain at least one reason code"`

### PUBREL Packet Validation

#### Fixed Header Flags
PUBREL packets must have fixed header flags set to `0010` (bit 1 = 1, others = 0).

**Error Message:**
- `"Invalid PUBREL flags: expected 0x02, got 0x{flags:02x}"`

### PINGREQ Packet Validation

#### Remaining Length Validation
PINGREQ packets must have remaining length of 0.

**Error Message:**
- `"PINGREQ packet must have remaining length of 0"`

#### Fixed Header Flags
PINGREQ packets must have fixed header flags set to `0000` (all reserved bits = 0).

**Error Message:**
- `"PINGREQ packet has invalid fixed header flags"`

### PINGRESP Packet Validation

#### Remaining Length Validation
PINGRESP packets must have remaining length of 0.

**Error Message:**
- `"PINGRESP packet must have remaining length of 0"`

#### Fixed Header Flags
PINGRESP packets must have fixed header flags set to `0000` (all reserved bits = 0).

**Error Message:**
- `"PINGRESP packet has invalid fixed header flags"`

### DISCONNECT Packet Validation

#### Fixed Header Flags
DISCONNECT packets must have fixed header flags set to `0000` (all reserved bits = 0).

**Error Message:**
- `"DISCONNECT packet has invalid fixed header flags"`

### AUTH Packet Validation

#### Fixed Header Flags
AUTH packets must have fixed header flags set to `0000` (all reserved bits = 0).

**Error Message:**
- `"AUTH packet has invalid fixed header flags"`

#### Reason Code Requirement
AUTH packets with remaining length > 0 must contain a reason code.

**Error Message:**
- `"AUTH packet must contain a reason code"`


## Unimplemented Features

### MQTTv5: 4.10: Request/Response

Using request/response in a pub/sub system is error-prone, use HTTP-based request/response instead.


## Testing

The library includes comprehensive tests for all validation features:

```bash
# Run all tests with strict compliance (default)
cargo test

# Run all tests without strict compliance  
cargo test --no-default-features

# Run only protocol compliance tests
cargo test protocol_compliance_tests
```

## Backward Compatibility

When `strict-protocol-compliance` is **disabled**, the library maintains backward compatibility and only performs basic validations that were already implemented. This ensures that existing code continues to work without changes.

When `strict-protocol-compliance` is **enabled** (default), the library provides maximum compliance with the MQTT 5.0 specification, which may reject some packets that were previously accepted.

## Examples

```rust
use flowsdk::mqtt_serde::encode_utf8_string;

// With strict-protocol-compliance enabled (default):
let result = encode_utf8_string("hello\u{0000}world");
assert!(result.is_err()); // Rejected due to null character

// With strict-protocol-compliance disabled:
// The same string would be accepted (only length validation)
```

```rust
use flowsdk::mqtt_serde::mqttv5::subscribe::TopicSubscription;

// With strict-protocol-compliance enabled:
let result = TopicSubscription::from_bytes(b"$share/group/topic\x80"); // Invalid subscription options
assert!(result.is_err()); // Rejected due to reserved bits

// With strict-protocol-compliance disabled:
// Reserved bits validation is not performed
```