1 个不稳定版本
0.1.0 | 2024年4月11日 |
---|
#81 在 #impl
用于 amass
25KB
674 行
amass
自动为嵌套枚举生成 From
实现,甚至跨crate。
只需要对每个嵌套枚举应用一个属性。
示例
pub mod letter {
pub struct A;
pub struct B;
pub struct C;
#[amass::amass_telety(crate::letter)]
pub enum Letter {
A(A),
B(B),
C(C),
}
}
pub mod number {
pub struct One;
pub struct Two;
pub struct Three;
#[amass::amass_telety(crate::number)]
pub enum Number {
One(One),
Two(Two),
Three(Three),
}
}
use letter::Letter;
use number::Number;
#[amass::amass_telety(crate)]
pub enum Alphanumeric {
Letter(Letter),
Number(Number),
}
pub struct Underscore;
#[amass::amass_telety(crate)]
pub enum IdentifierChar {
Alphanumeric(Alphanumeric),
Underscore(Underscore),
}
fn main() {
let _: &[IdentifierChar] = &[
letter::A.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Letter(Letter::A(A)))
letter::B.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Letter(Letter::B(B)))
letter::C.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Letter(Letter::C(C)))
Underscore.into(), // IdentifierChar::Underscore(Underscore)
number::One.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Number(Number::One(One)))
number::Two.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Number(Number::Two(Two)))
number::Three.into(), // IdentifierChar::Alphanumeric(Alphanumeric::Number(Number::Three(Three)))
];
}
amass 由 telety 驱动,它在其支持的语言功能上仍有 限制。 您可以单独使用 #[amass]
和 #[telety(...)]
属性,或者简单地使用组合的 #[amass_telety(...)]
属性。
指定实现
amass 对适用的字段有可定制的行为。以下选项存在
- 忽略 - 不会为字段类型或该类型包含的字段类型创建任何 From 实现。
- 浅 - 将为字段类型创建一个 From 实现,但不会为该类型包含的字段类型创建实现。
- 深 - 将为字段类型创建一个 From 实现,如果该类型已启用 telety,则为该类型包含的字段类型创建实现。
- 强制 - 将为字段类型及其包含的字段类型创建 From 实现。如果类型未启用 telety,将生成编译错误。
可以在主属性上指定默认操作:#[amass(default = force)]
。如果该属性未提供默认值,则默认操作为deep
。
可以通过#[amass_action(...)]
辅助属性来覆盖特定变体的默认值。
#[amass_telety(crate)]
pub enum ConflictingVariants {
Default(i32),
#[amass_action(ignore)]
Alternate(i32),
}
#[amass_telety(crate, default = ignore)]
pub enum ConflictingVariants {
#[amass_action(shallow)]
Default(i32),
Alternate(i32),
}
请注意,目前无法在上游枚举上覆盖行为。
在这个例子中,为From<DiamondTop> for DiamondBottom
生成了两个impl,导致编译错误。
# use amass::amass_telety;
pub struct DiamondTop;
#[amass_telety(crate)]
pub struct DiamondLeft {
Top(DiamondTop)
}
#[amass_telety(crate)]
pub struct DiamondRight {
Top(DiamondTop)
}
#[amass_telety(crate)]
pub struct DiamondBottom {
Left(DiamondLeft),
Right(DiamondRight),
}
# fn main() { }
为了解决这个问题,必须使DiamondLeft
或DiamondRight
忽略Top
变体,或者DiamondBottom
必须为Left
或Right
变体使用shallow
。无法仅跳过DiamondTop
-> DiamondLeft
/DiamondRight
-> DiamondBottom
的impl。
依赖
~0.4–1MB
~22K SLoC