7 个版本
0.2.2 | 2022年2月6日 |
---|---|
0.2.1 | 2021年2月9日 |
0.2.0 | 2020年10月12日 |
0.1.3 | 2019年10月28日 |
0.1.2 | 2019年9月25日 |
#120 in 过程宏
523,518 每月下载量
用于 1,893 个crate(其中65个直接使用)
55KB
1K SLoC
impl-trait-for-tuples
为元组实现特质的属性宏
简介
当想要为元组的组合实现一个特质时,Rust要求必须手动为每个组合实现该特质。使用此crate,您只需要在特质声明上方放置 #[impl_for_tuples(5)]
(在全自动模式下)以实现以下元组组合的特质: (), (T0), (T0, T1), (T0, T1, T2), (T0, T1, T2, T3), (T0, T1, T2, T3, T4, T5)
。元组的数量是属性宏的参数,可以自由选择。
此crate提供两种模式:全自动和半自动。全自动模式只需定义特征,然后实现特征即可为元组组合实现特征。虽然使用起来非常方便,但也存在一些限制,例如不支持关联类型、返回值或关联常量。为了支持这些功能,提供了半自动模式。这种模式需要为特征提供一个空实现块,该空实现块被扩展为所有元组组合的实现。在这个空实现中,要表达元组访问,需要使用特殊的语法for_tuples!( #( Tuple::function(); )* )
。这将扩展为Tuple::function();
,对于每个元组,其中Tuple
由用户选择,并在每次迭代中替换为相应的元组标识符。
语法
属性宏可以使用一个参数#[impl_for_tuples(5)]
或两个参数#[impl_for_tuples(2, 5)]
进行调用。前者指示宏生成最多包含五个元素的元组,后者指示宏生成从包含两个元素的元组到五个元素的元组。
半自动语法
trait Trait {
type Ret;
type Arg;
type FixedType;
const VALUE: u32;
fn test(arg: Self::Arg) -> Self::Ret;
fn test_with_self(&self) -> Result<(), ()>;
}
#[impl_for_tuples(1, 5)]
impl Trait for Tuple {
// Here we expand the `Ret` and `Arg` associated types.
for_tuples!( type Ret = ( #( Tuple::Ret ),* ); );
for_tuples!( type Arg = ( #( Tuple::Arg ),* ); );
for_tuples!( const VALUE: u32 = #( Tuple::VALUE )+*; );
// Here we set the `FixedType` to `u32` and add a custom where bound that forces the same
// `FixedType` for all tuple types.
type FixedType = u32;
for_tuples!( where #( Tuple: Trait<FixedType=u32> )* );
fn test(arg: Self::Arg) -> Self::Ret {
for_tuples!( ( #( Tuple::test(arg.Tuple) ),* ) )
}
fn test_with_self(&self) -> Result<(), ()> {
for_tuples!( #( Tuple.test_with_self()?; )* );
Ok(())
}
}
给定的示例显示了所有支持的for_tuples!
组合。当访问自元组实例的方法时,需要使用self.Tuple
的语法,并被替换为self.0
、self.1
等。占位符元组标识符取自实现块中提供的自类型。因此,用户可以选择任何有效的标识符。
提供给#( Tuple::something() )SEPARATOR*
的分隔符可以是,
、+
、-
、*
、/
、|
、&
或什么都不用,表示没有分隔符。
通过在impl块上方添加#[tuple_types_no_default_trait_bound]
,宏将不会为每个元组类型自动添加实现的特征限制。
可以使用以下代码自定义特质边界:#[tuple_types_custom_trait_bound(NewBound)]
。新边界将替代每个元组类型的实现特质。
限制
该宏不支持在不同宏中调用 for_tuples!
,因此类似 vec![ for_tuples!( bla ) ]
的代码将生成无效代码。
示例
全自动
#[impl_for_tuples(5)]
trait Notify {
fn notify(&self);
}
半自动
trait Notify {
fn notify(&self) -> Result<(), ()>;
}
#[impl_for_tuples(5)]
impl Notify for TupleIdentifier {
fn notify(&self) -> Result<(), ()> {
for_tuples!( #( TupleIdentifier.notify()?; )* );
Ok(())
}
}
许可协议
以下任一许可协议下使用
许可证:Apache-2.0/MIT
依赖项
~1.5MB
~36K SLoC