batch-impl
为 Rust trait 批量生成 impl 块的过程宏库——一行 DSL,展开成 N 个 impl。
use batch_impl;
# use Rc;
// 一个 body,为 4 种类型各生成一个 impl
// → impl<T> Sortable<T> for Box<Vec<T>> where T: Ord { ... }
// → impl<T> Sortable<T> for Rc<Vec<T>> where T: Ord { ... }
// 一行生成 4 个带泛型的元组 impl
// → impl<A> TupleTrait for (A,) {}
// → impl<A, B> TupleTrait for (A, B) {}
// → impl<A, B, C> TupleTrait for (A, B, C) {}
// → impl<A, B, C, D> TupleTrait for (A, B, C, D) {}
为什么要用它
为多个类型实现同一 trait,手写意味着重复:签名抄 N 遍、body 复制 N 份、 泛型参数与关联类型各写各的、改一处漏三处。batch-impl 把 impl 的数量交给人脑 之外的描述:
- 一处真相源:trait 定义只写一次(签名/泛型/bound/where 约束),DSL 只写 "哪些类型 × 什么实现",其余由宏补齐——签名、泛型 bound、关联类型绑定、 甚至 trait 级 where 约束都从 trait 定义自动继承,与手写完全等价。
- 一行矩阵:
[...]列表、^/-应用、()^N元组生成,一条 DSL 描述 "类型矩阵",宏对每个格子生成一个 impl。 - 批量但不失手写质感:
{ body }是普通 Rust 代码,#指令自动抄签名, 生成的 impl 与手写逐 token 等价——rustc 能验证什么,它就能验证什么。
一个真实场景(见 examples/simplify.rs):12 个数值类型 + 4 个包装类型 +
4 个元组 + 若干杂项 = 29 个 impl,约 15 行 DSL,手写约 80 行。
心智模型
你写的是一条"类型矩阵"的描述,batch-impl 对矩阵的每个格子生成 impl:
#[batch_impl( <impl-泛型> Trait名<trait-泛型> 目标类型矩阵 { body }? )]
| 记号 | 含义 | 直觉 |
|---|---|---|
^ / - |
应用:把左侧容器/修饰符作用到右侧类型 | 同一个运算,仅结合性不同 |
[A, B] |
列表 | 横向展开(笛卡尔积) |
(A, B) |
元组 | 排列(有序对) |
#name |
指令:从 trait 定义自动抄 item 签名 | body 不用手写签名 |
^ 与 - 是同一运算(左侧是修饰符/容器,右侧是目标类型),区别只在结合方向:
^右结合,链式产生嵌套:Box^Box^T=Box<Box<T>>,HashMap^K^V=HashMap<K<V>>-左结合,链式累加参数:HashMap-K-V=HashMap<K, V>,fn(A, B)-C=fn(A, B) -> C
所以选哪个只看你想要的分组形状:想套娃用 ^,想并列参数用 -。
[A, B]^[X, Y] = 2×2 矩阵(4 个 impl);(T1, T2)^2 = 排列(4 个有序对)。
快速开始
[]
= "0.6.0"
需要 Rust 2024 edition 及以上。
use batch_impl;
// 1. 定义 trait,方法签名只写一次
// 2. 写一条 DSL:目标类型 + body(方法签名用 #name 自动从 trait 抄)
// → impl Tagged for usize { fn name(&self) -> &str { "number" } }
// → impl Tagged for isize { fn name(&self) -> &str { "number" } }
// → impl Tagged for String { fn name(&self) -> &str { "string" } }
特性一览
| 特性 | 一句话 | 教程章节 |
|---|---|---|
并列列表 [A, B] |
为多个类型同时实现,body 复用 | 列表与 body |
^ / - 运算符 |
同一运算的右/左结合:嵌套与累加 | 运算符 |
| 泛型自动化 | A<> 照抄、同名继承、trait where 子句继承 |
泛型自动化 |
| 关联类型绑定 | Iter<Item=T> → type Item = T; |
关联类型 |
指令系统 #name/#fill/#delegate |
签名自动抄、body 批量填、委托调用 | 指令系统 |
覆盖式委托 #blanket |
包装矩阵一行生成委托 impl(任意包装 + :N、泛型 trait、assoc 投影) |
指令系统 |
| 开放扩展 | 不认识的 #name(args){body} 交给你的同名宏 |
指令系统 |
@ 常量 |
@uint/@scalar/@u8..u128 + batch_trait! 自定义(懒展开、链式引用) |
常量系统 |
where{...} |
为生成的 impl 附加 where 子句 | where 子句 |
| 元组生成 | ()^3、(T,)^N、笛卡尔积、范围 |
元组生成 |
| fn 类型 / unsafe / 指针 / 属性 | 类型级修饰符全支持 | 修饰符 |
下一步
- 完整教程:
docs/tutorial.md(渐进式从一行 impl 到高级矩阵组合) - 三个入口:
#[batch_impl](含 trait)/#[batch_impl_only](只出 impl)/batch_trait!(对已声明 trait 批量生成,支持多段) - 示例:
examples/quickstart.rs(特性 demo)、examples/simplify.rs(29 个 impl ≈ 15 行 DSL 的真实场景) - 开发者:内部架构见
docs/architecture.md,开发变更记录见docs/dev-changelog.md
许可证
MIT OR Apache-2.0