Procedural macro implementation for asyncapi-rust
This crate provides the procedural macros that power asyncapi-rust, enabling
compile-time generation of AsyncAPI 3.0 specifications from Rust code.
Overview
Two derive macros are provided:
#[derive(ToAsyncApiMessage)]
Generates message metadata and JSON schemas from Rust types (structs or enums).
- Works with
serdefor serialization patterns - Uses
schemarsfor JSON Schema generation - Supports
#[asyncapi(...)]helper attributes for documentation - Generates methods:
asyncapi_message_names(),asyncapi_messages(), etc.
Example:
use ;
use ;
// Generated methods available:
let names = asyncapi_message_names;
let messages = asyncapi_messages; // Requires JsonSchema
#[derive(AsyncApi)]
Generates complete AsyncAPI 3.0 specifications with servers, channels, and operations.
- Requires
titleandversionattributes - Supports optional
descriptionattribute - Use
#[asyncapi_server(...)]to define servers - Use
#[asyncapi_channel(...)]to define channels - Use
#[asyncapi_operation(...)]to define operations - Can use multiple of each attribute type
Example:
use AsyncApi;
;
// Generated method:
let spec = asyncapi_spec;
Supported Attributes
#[asyncapi(...)] on message types
Helper attributes for documenting messages (used with ToAsyncApiMessage):
summary = "..."- Short summary of the messagedescription = "..."- Detailed descriptiontitle = "..."- Human-readable title (defaults to message name)content_type = "..."- Content type (defaults to "application/json")triggers_binary- Flag for binary messages (sets content_type to "application/octet-stream")
#[asyncapi(...)] on API specs
Required attributes for complete specifications (used with AsyncApi):
title = "..."- API title (required)version = "..."- API version (required)description = "..."- API description (optional)
#[asyncapi_server(...)]
Define server connection information:
name = "..."- Server identifier (required)host = "..."- Server host/URL (required)protocol = "..."- Protocol (e.g., "wss", "ws", "grpc") (required)description = "..."- Server description (optional)
#[asyncapi_channel(...)]
Define communication channels:
name = "..."- Channel identifier (required)address = "..."- Channel path/address (optional)
#[asyncapi_operation(...)]
Define send/receive operations:
name = "..."- Operation identifier (required)action = "send"|"receive"- Operation type (required)channel = "..."- Channel reference (required)
Integration with serde
The macros respect serde attributes for naming and structure:
#[serde(rename = "...")]- Use custom name in AsyncAPI spec#[serde(tag = "...")]- Tagged enum with discriminator field#[serde(skip)]- Exclude fields from schema#[serde(skip_serializing_if = "...")]- Optional fields
Integration with schemars
JSON schemas are generated automatically using schemars:
- Requires
JsonSchemaderive on message types - Generates complete JSON Schema from Rust type definitions
- Supports nested types, generics, and references
- Schemas include validation rules from type constraints
Generated Code
The macros generate implementations with these methods:
From ToAsyncApiMessage:
asyncapi_message_names() -> Vec<&'static str>- Get all message namesasyncapi_message_count() -> usize- Number of messagesasyncapi_tag_field() -> Option<&'static str>- Serde tag field if presentasyncapi_messages() -> Vec<Message>- Generate messages with schemas
From AsyncApi:
asyncapi_spec() -> AsyncApiSpec- Generate complete specification
Implementation Notes
- All code generation happens at compile time (proc macros)
- Zero runtime cost - generates plain Rust code
- Compile errors if documentation drifts from code
- Type-safe - uses Rust's type system for validation