#tuple #traits #proc-macro #macro #crates

impl-trait-for-tuples

为元组实现特质的属性宏

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 过程宏

Download history 130347/week @ 2024-03-14 136929/week @ 2024-03-21 132650/week @ 2024-03-28 148368/week @ 2024-04-04 147505/week @ 2024-04-11 147084/week @ 2024-04-18 129787/week @ 2024-04-25 132772/week @ 2024-05-02 132685/week @ 2024-05-09 127555/week @ 2024-05-16 134086/week @ 2024-05-23 137149/week @ 2024-05-30 121695/week @ 2024-06-06 134065/week @ 2024-06-13 139558/week @ 2024-06-20 104632/week @ 2024-06-27

523,518 每月下载量
用于 1,893 个crate(其中65个直接使用)

Apache-2.0/MIT

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.0self.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