batch-impl 0.6.0

A proc-macro library for batch generating trait impls with a powerful DSL
Documentation

batch-impl

为 Rust trait 批量生成 impl 块的过程宏库——一行 DSL,展开成 N 个 impl

use batch_impl::batch_impl;
# use std::rc::Rc;

// 一个 body,为 4 种类型各生成一个 impl
#[batch_impl(<T> Sortable<T> [Box, Rc]^Vec<T> where T: Ord  {
    fn is_sorted(&self) -> bool { self.windows(2).all(|w| w[0] <= w[1]) }
})]
trait Sortable<T> { fn is_sorted(&self) -> bool; }
// → impl<T> Sortable<T> for Box<Vec<T>> where T: Ord { ... }
// → impl<T> Sortable<T> for Rc<Vec<T>>  where T: Ord { ... }

// 一行生成 4 个带泛型的元组 impl
#[batch_impl(()^4)]
trait TupleTrait {}
// → 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 个有序对)。

快速开始

[dependencies]

batch-impl = "0.6.0"

需要 Rust 2024 edition 及以上。

use batch_impl::batch_impl;

// 1. 定义 trait,方法签名只写一次
trait Describe { fn describe(&self) -> String; }

// 2. 写一条 DSL:目标类型 + body(方法签名用 #name 自动从 trait 抄)
#[batch_impl(
    [usize, isize] #name{"number"},
    String #name{"string"}
)]
trait Tagged { fn name(&self) -> &str; }
// → 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