一键导入
rust-macro
Macro and procedural metaprogramming expert covering macro_rules!, derive macros, proc-macros, compile-time computation, and code generation patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Macro and procedural metaprogramming expert covering macro_rules!, derive macros, proc-macros, compile-time computation, and code generation patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Actor model expert covering message passing, state isolation, supervision trees, deadlock prevention, fault tolerance, Actix framework, and Erlang-style concurrency patterns.
Rust anti-patterns and common mistakes expert. Handles code review issues with clone abuse, unwrap in production, String misuse, index loops, and refactoring guidance.
Advanced async patterns expert covering Stream implementation, zero-copy buffers, tokio::spawn lifetimes, plugin system scheduling, tonic streaming, and async lifetime management.
Advanced async patterns expert. Handles Stream processing, backpressure control, select/join operations, cancellation, Future trait implementation, and async runtime optimization.
Authentication and authorization expert covering JWT, API keys, OAuth, RBAC, password hashing, distributed token storage, and session management patterns.
Caching and distributed storage expert covering Redis, connection pools, TTL strategies, cache patterns (Cache-Aside, Write-Through), invalidation, and performance optimization.
| name | rust-macro |
| description | Macro and procedural metaprogramming expert covering macro_rules!, derive macros, proc-macros, compile-time computation, and code generation patterns. |
| metadata | {"triggers":["macro","derive","proc-macro","macro_rules","metaprogramming","code generation","compile-time"]} |
| Dimension | Macros | Generics |
|---|---|---|
| Flexibility | Code transformation | Type abstraction |
| Compile cost | Incremental-friendly | Monomorphization overhead |
| Error messages | Can be cryptic | Clear |
| Debugging | Debug expanded code | Direct debugging |
| Use case | Reduce boilerplate | Generic algorithms |
// Basic structure
macro_rules! my_vec {
// Empty case
() => {
Vec::new()
};
// List of elements
($($elem:expr),* $(,)?) => {{
let mut v = Vec::new();
$(
v.push($elem);
)*
v
}};
// Repeated element
($elem:expr; $n:expr) => {
vec![$elem; $n]
};
}
// Usage
let v1 = my_vec![];
let v2 = my_vec![1, 2, 3];
let v3 = my_vec![0; 10];
// In a separate proc-macro crate
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(Builder)]
pub fn derive_builder(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
let builder_name = format!("{}Builder", name);
let builder_ident = syn::Ident::new(&builder_name, name.span());
let fields = match &input.data {
syn::Data::Struct(data) => &data.fields,
_ => panic!("Builder only works on structs"),
};
let field_names: Vec<_> = fields.iter()
.filter_map(|f| f.ident.as_ref())
.collect();
let field_types: Vec<_> = fields.iter()
.map(|f| &f.ty)
.collect();
let expanded = quote! {
pub struct #builder_ident {
#(#field_names: Option<#field_types>),*
}
impl #builder_ident {
pub fn new() -> Self {
Self {
#(#field_names: None),*
}
}
#(
pub fn #field_names(mut self, value: #field_types) -> Self {
self.#field_names = Some(value);
self
}
)*
pub fn build(self) -> Result<#name, String> {
Ok(#name {
#(
#field_names: self.#field_names
.ok_or_else(|| format!("Field {} not set", stringify!(#field_names)))?
),*
})
}
}
impl #name {
pub fn builder() -> #builder_ident {
#builder_ident::new()
}
}
};
expanded.into()
}
#[proc_macro]
pub fn sql(input: TokenStream) -> TokenStream {
let sql_string = input.to_string();
// Parse and validate SQL at compile time
validate_sql(&sql_string);
// Generate code
quote! {
QueryBuilder::raw(#sql_string)
}.into()
}
// Usage:
let query = sql!("SELECT * FROM users WHERE id = ?");
#[proc_macro_attribute]
pub fn cached(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemFn);
let fn_name = &input.sig.ident;
let fn_body = &input.block;
let expanded = quote! {
fn #fn_name() -> Result {
use std::sync::OnceLock;
static CACHE: OnceLock<Result> = OnceLock::new();
CACHE.get_or_init(|| {
#fn_body
}).clone()
}
};
expanded.into()
}
// Usage:
#[cached]
fn expensive_computation() -> String {
// ...
}
| Syntax | Meaning |
|---|---|
$() | Match zero or more |
$($x),* | Comma-separated |
$($x),+ | At least one |
$x:ty | Type matcher |
$x:expr | Expression matcher |
$x:pat | Pattern matcher |
$x:ident | Identifier matcher |
$x:path | Path matcher |
$x:tt | Token tree matcher |
// Example: multiple matchers
macro_rules! create_struct {
($name:ident { $($field:ident: $type:ty),* }) => {
struct $name {
$($field: $type),*
}
};
}
create_struct!(User {
id: u64,
name: String,
email: String
});
Need to reduce duplication?
→ Can generics solve it? Prefer generics
→ Need syntax transformation? Use macros
→ Need to inspect types? Derive macro
→ Need attribute? Attribute macro
Declarative (macro_rules!)?
✅ Simple pattern matching
✅ Quick to write
❌ Limited power
Procedural (proc-macro)?
✅ Full AST access
✅ Complex transformations
❌ Separate crate needed
❌ Longer compile times
# Expand macros
cargo expand
# Expand specific function
cargo expand my_module::my_function
# Expand tests
cargo expand --test test_name
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_macro_expansion() {
// Test generated code
let result = my_macro!(input);
assert_eq!(result, expected);
}
}
| Crate | Purpose |
|---|---|
| syn | Parse Rust syntax |
| quote | Generate Rust code |
| proc-macro2 | Token manipulation |
| derive-more | Common derive macros |
| darling | Parse macro attributes |
| Practice | Reason |
|---|---|
| Try generics first | Safer, easier to debug |
| Keep macros simple | Complex macros hard to maintain |
| Document macros | Users need to understand expansion |
| Test expansion | Ensure correctness |
| Use cargo expand | Visualize macro output |
When reviewing macro code:
# Expand macros
cargo expand
# Expand specific module
cargo expand path::to::module
# Check proc-macro crate
cargo check -p my-proc-macro
# Test expansion
cargo test --all-features
Symptom: Unexpected variable captures
// ❌ Bad: name clash risk
macro_rules! bad_macro {
($x:expr) => {{
let result = $x; // 'result' might clash
result
}};
}
// ✅ Good: use unique names
macro_rules! good_macro {
($x:expr) => {{
let __macro_result = $x;
__macro_result
}};
}
Symptom: Users don't understand macro errors
// ✅ Good: helpful error messages
macro_rules! require_trait {
($t:ty) => {
const _: fn() = || {
fn assert_impl<T: MyTrait>() {}
assert_impl::<$t>();
};
};
}
Symptom: Slow incremental builds
// ❌ Avoid: heavy proc macros for simple tasks
#[derive(HeavyProcMacro)]
struct Simple {
field: String,
}
// ✅ Better: manual impl or simpler derive
impl Simple {
// Manual implementation
}