8 个稳定版本

3.1.0 2024年4月21日
3.0.1 2024年4月5日
3.0.0 2024年3月26日
2.0.3 2024年3月10日
1.0.0 2024年2月26日

#9 in #delegation

Download history • Rust 包仓库 10/week @ 2024-04-09 • Rust 包仓库 158/week @ 2024-04-16 • Rust 包仓库 28/week @ 2024-04-23 • Rust 包仓库 6/week @ 2024-05-21 • Rust 包仓库 1/week @ 2024-05-28 • Rust 包仓库 5/week @ 2024-06-04 • Rust 包仓库 16/week @ 2024-06-11 • Rust 包仓库 80/week @ 2024-06-18 • Rust 包仓库 2/week @ 2024-06-25 • Rust 包仓库 10/week @ 2024-07-02 • Rust 包仓库 69/week @ 2024-07-23 • Rust 包仓库

79 每月下载量
用于 sux

MPL-2.0 许可证

95KB
3K SLoC

该 crate 提供了一般机制,通过转发其他类型提供的实现来在类型上实现特性。

提供了两种不同的转发方法:通过成员实现的特性转发,以及通过可以将接收者类型转换为的类型实现的特性转发。这些方法可以在同一接收者类型上组合使用。此 crate 完全支持泛型特性和结构体类型。

有关更多详细信息,请参阅 crate 文档


lib.rs:

该 crate 提供了一般机制,通过转发其他类型提供的实现来在类型上实现特性。

提供了两种不同的转发方法:通过成员实现的特性转发,以及通过可以将接收者类型转换为的类型实现的特性转发。这些方法可以在同一接收者类型上组合使用。此 crate 完全支持泛型特性和结构体类型。

有关功能和限制的更多详细信息,请参阅各个宏的文档页面。

基础

为了转发一个特性,需要一些基本的东西。

use forward_traits::{forwardable, forward_receiver, forward_traits};

我们需要一个特性定义,该定义带有用于生成转发实现的信息。这是通过将 #[forwardable] 属性应用于定义来完成的。

#[forwardable]
trait FooTrait
{
type Bar;

fn foo (&self) -> &Self::Bar;

const BAZ: u32;
}

然后我们需要一个最初实现此特性的类型。

struct A {}

impl FooTrait for A
{
type Bar = Self;

fn foo (&self) -> &Self::Bar { self }

const BAZ: u32 = 42;
}

接下来,我们需要一个类型,我们想要通过转发在最初实现类型上找到的实现来实现此特性。有几种不同的方法来定义此类类型,但在这里我们将演示 newtype 习惯用法。此类型需要带有 #[forward_receiver] 属性。

#[forward_receiver]
struct B (A);

最后,我们需要指定我们想要转发一个特性。在这种情况下,我们想要转发由成员实现的特性,所以我们写

forward_traits! (for B . 0 impl FooTrait);

现在我们可以看到特性已正确转发。

assert_eq! (<B as FooTrait>::BAZ, 42);

重新导出可转发特性

在重新导出可传递特性时,应将 #[forwardable] 属性应用于使用语句。请注意,该属性将解释使用树中的每个项作为应可传递的特性。如果您想从同一模块(或模块集)中重新导出不是可传递特性的项,则需要将这些重新导出分开到另一个使用语句中;

use forward_traits::forwardable;

mod inner
{
use forward_traits::forwardable;

#[forwardable]
pub trait Foo {}

pub struct Bar {}
}

#[forwardable]
pub use inner::Foo;

pub use inner::Bar;

其他包中的特性

可传递特性与在其他包中的特性一起工作,只要这些特性定义注解了 #[forwardable]

如果没有,则必须单独提供注解。以这种方式提供注解时,特性将在注解宏的位置导入(如果提供了可见性修饰符,则重新导出)。在转发此特性时,您必须引用此导入/导出(或其重新导出)。

use forward_traits
::{
supply_forwarding_info_for_trait,
forward_receiver,
forward_traits
};

// This has the side-effect of importing IntoIterator into the current scope.
supply_forwarding_info_for_trait!
(
std::iter::IntoIterator,
trait
{
type Item;
type IntoIter;
fn into_iter (self) -> Self::IntoIter;
}
);

#[forward_receiver]
struct VecWrapper <T> (Vec <T>);

// Note that we are referring to the IntoIterator in the current scope.
forward_traits! (for VecWrapper . 0 impl IntoIterator);

// Now we can call the trait method on the wrapper type.
VecWrapper (vec! (1, 2, 3)) . into_iter ();

依赖项

~320–780KB
~18K SLoC