Procedural macros for RocketMQ-Rust protocol types, request headers, and remoting serialization helpers.
rocketmq-macros is a small proc-macro crate used by the RocketMQ-Rust workspace to remove repetitive protocol glue
from request and response header definitions. Its primary job is to generate CommandCustomHeader and FromMap
implementations for RocketMQ remoting headers, preserving Java-compatible wire keys while keeping the Rust structs
typed and maintainable.
This crate is infrastructure, not a runtime component. Most application code should use the higher-level
rocketmq-remoting, rocketmq-client-rust, rocketmq-broker, or service crates instead of depending on these macros
directly.
| Macro | Status | What it generates |
|---|---|---|
RequestHeaderCodecV2 |
Primary | CommandCustomHeader::to_map and FromMap::from for named Rust structs, with optimized map decoding, required-field checks, serde(rename), serde(alias), and flattened nested headers. |
RequestHeaderCodec |
Compatibility | Earlier request-header codec derive with Java-style camelCase keys, #[required], optional fields, primitive parsing, and flattened nested headers. |
RemotingSerializable |
Utility | Implements crate::protocol::RemotingSerializable for a type. In most current remoting paths, serde-backed blanket implementations are preferred. |
typed protocol header struct
|
| #[derive(RequestHeaderCodecV2)]
v
generated constants + CommandCustomHeader::to_map()
|
v
RocketMQ remoting ext fields: HashMap<CheetahString, CheetahString>
|
v
generated FromMap::from() with required-field validation and parsing
The generated code intentionally targets the protocol contracts used by rocketmq-remoting:
crate::protocol::command_custom_header::CommandCustomHeadercrate::protocol::command_custom_header::FromMapcrate::protocol::RemotingSerializablecheetah_string::CheetahStringrocketmq_error::RocketMQError
Because the expansion uses crate::protocol... paths, these macros are intended for crates that expose compatible
protocol modules. Inside this workspace, that is primarily rocketmq-remoting.
Use RequestHeaderCodecV2 on a named struct that represents a RocketMQ remoting header:
use rocketmq_macros::RequestHeaderCodecV2;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default, RequestHeaderCodecV2)]
#[serde(rename_all = "camelCase")]
pub struct SendMessageRequestHeader {
#[required]
pub producer_group: cheetah_string::CheetahString,
#[required]
pub topic: cheetah_string::CheetahString,
pub queue_id: Option<i32>,
pub sys_flag: i32,
pub born_timestamp: i64,
pub batch: Option<bool>,
}The derive generates:
- associated string constants for the wire keys;
CommandCustomHeader::to_map, omittingNonevalues;FromMap::from, convertingCheetahStringmap values back into typed fields;- required-field errors for fields annotated with
#[required]; - default values for missing non-required, non-
Optionfields.
| Rust field shape | Serialization behavior | Deserialization behavior |
|---|---|---|
CheetahString |
Insert directly into the ext-field map. | Read directly, or default when not required. |
String |
Convert to CheetahString. |
Convert back to String. |
| Primitive types | Convert with to_string(). |
Parse with FromStr; required fields return a typed header error on parse failure. |
Option<T> |
Insert only when Some. |
Missing values become None; present primitive values are parsed. |
#[serde(flatten)] nested header |
Merge the nested header map. | Reconstruct by calling the nested type's FromMap::from. |
RequestHeaderCodecV2 uses the field name converted from snake_case to camelCase unless a serde(rename = "...")
attribute is present. serde(alias = "...") values are accepted during decoding for backwards-compatible wire names.
#[required] marks a header field that must be present during FromMap::from:
#[derive(RequestHeaderCodecV2)]
pub struct QueryMessageRequestHeader {
#[required]
pub topic: cheetah_string::CheetahString,
pub key: Option<cheetah_string::CheetahString>,
}This mirrors the intent of Java RocketMQ's @CFNotNull annotation. Missing required fields return
RocketMQError::DeserializeHeaderError with the generated wire-key name.
| Path | Purpose |
|---|---|
src/lib.rs |
Public proc-macro entry points and shared type helpers. |
src/request_header_custom.rs |
RequestHeaderCodec and RequestHeaderCodecV2 expansion logic. |
src/remoting_serializable.rs |
RemotingSerializable derive expansion. |
Cargo.toml |
Proc-macro crate configuration and macro parsing dependencies. |
- Rust
1.85.0or newer. - The repository toolchain from
../rust-toolchain.toml. - A consuming crate with compatible
crate::protocolmodule paths for generated protocol trait implementations.
Inside this workspace:
[dependencies]
rocketmq-macros = { path = "../rocketmq-macros" }For external consumers:
[dependencies]
rocketmq-macros = "1.0.0"External use is only practical when the consuming crate exposes the same protocol traits and supporting types expected by the generated code.
Focused checks for this crate:
cargo test -p rocketmq-macros --libBecause the macros are consumed heavily by rocketmq-remoting, validate downstream protocol headers after changing macro
generation logic:
cargo test -p rocketmq-remoting --libWorkspace-level Rust validation is run from the repository root when Rust code changes:
cargo fmt --all
cargo clippy --workspace --no-deps --all-targets --all-features -- -D warningsRocketMQ-Rust is licensed under the Apache License 2.0. See ../LICENSE-APACHE.