#convert #derive #telety #from #macro-derive

amass

自动为嵌套枚举生成 From 实现函数,即使跨越不同的crate

1 个不稳定版本

0.1.0 2024年4月11日

#1387Rust模式

MIT/Apache

34KB
53

amass

自动为嵌套枚举生成 From 实现函数。

只需要为每个嵌套枚举应用一个属性

示例

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 生成了两个实现,导致编译错误。

# 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() { }

为了解决这个问题,必须使 DiamondLeftDiamondRight 忽略 Top 变体,或者 DiamondBottom 必须为 LeftRight 变体使用 shallow。无法仅跳过 DiamondTop -> DiamondLeft/DiamondRight -> DiamondBottom 实现。

依赖关系

~0.4–1MB
~22K SLoC