plugins/languages/rust/skills/macros/SKILL.md
Rust 宏开发规范 — `macro_rules!` 声明宏(卫生性、完整路径、递归 / 重复模式)、过程宏(derive / 属性 / 函数式)、proc-macro2 + syn 2.x + quote 工具链、trybuild 编译测试、cargo-expand 展开验证、`compile_error!` span 精确报错。设计宏 API、实现 derive 宏、做代码生成 / 元编程时加载。触发短语:macro_rules、proc-macro、derive 宏、属性宏、syn、quote、代码生成、宏展开、元编程。
npx skillsauth add lazygophers/ccplugin rust-macrosInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
前置:rust-core。
| 需求 | 方案 |
|------|------|
| 简单重复模式(DSL) | macro_rules! |
| 自动实现 trait | derive 过程宏 |
| 改装函数 / 结构体 | 属性过程宏 |
| 函数式 DSL | 函数式过程宏 |
| 首选 | 泛型 + trait 解决,无法解决再宏 |
宏是代码生成器,不是抽象工具。能用类型系统解决的问题禁止上宏。
macro_rules! 模板macro_rules! hashmap {
($($k:expr => $v:expr),* $(,)?) => {{
let mut m = ::std::collections::HashMap::new();
$(m.insert($k, $v);)*
m
}};
}
let m = hashmap! { "a" => 1, "b" => 2, };
卫生性铁律:宏内引用 std / 第三方类型必须用 ::std::... / ::serde::... 完整路径,避免调用方命名空间污染。
Cargo.toml:
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1"
syn = { version = "2", features = ["full"] }
quote = "1"
Derive 宏示例:
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Data, Fields};
#[proc_macro_derive(Builder)]
pub fn derive_builder(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
let builder = syn::Ident::new(&format!("{name}Builder"), name.span());
let fields = match &ast.data {
Data::Struct(s) => match &s.fields {
Fields::Named(f) => &f.named,
_ => return syn::Error::new_spanned(name, "Builder requires named fields")
.to_compile_error().into(),
},
_ => return syn::Error::new_spanned(name, "Builder requires struct")
.to_compile_error().into(),
};
let setters = fields.iter().map(|f| {
let n = &f.ident; let t = &f.ty;
quote! { pub fn #n(mut self, v: #t) -> Self { self.#n = Some(v); self } }
});
quote! {
impl #builder {
#(#setters)*
}
}.into()
}
属性宏(函数包装):
#[proc_macro_attribute]
pub fn timed(_attr: TokenStream, item: TokenStream) -> TokenStream {
let f = parse_macro_input!(item as syn::ItemFn);
let sig = &f.sig; let block = &f.block; let vis = &f.vis;
let name = &sig.ident;
quote! {
#vis #sig {
let _t = ::std::time::Instant::now();
let _r = (|| #block)();
::tracing::info!(fn = stringify!(#name), elapsed_ms = _t.elapsed().as_millis());
_r
}
}.into()
}
宏内部禁止 panic!;用 syn::Error::new_spanned(...).to_compile_error() 在出错位置给出 IDE 友好提示。
return syn::Error::new_spanned(field, "expected `#[builder(default)]`")
.to_compile_error().into();
// trybuild:验证编译通过 / 失败
#[test]
fn ui() {
let t = trybuild::TestCases::new();
t.pass("tests/expand/*.rs");
t.compile_fail("tests/fail/*.rs");
}
cargo expand --test <name> 验证展开结果,作为开发期 review 工具。
| AI 倾向 | 正确做法 |
|---------|---------|
| 万物皆可宏 | 先用泛型 + trait |
| syn 1.x | 升级到 syn 2.x |
| panic! 报错 | Error::to_compile_error |
| 宏内裸 String | 完整路径 ::std::string::String |
| 不写测试 | trybuild + cargo expand |
macro_rules! 使用 :: 完整路径syn 2.x + quotesyn::Error::to_compile_error 而非 panic!trybuild 编译测试tools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。