#枚举 #derive-debug #no-std

no-std subenum

一个用于创建枚举子集的进程宏,可以转换到和从

6个版本 (稳定)

1.1.2 2024年3月12日
1.1.1 2023年9月19日
1.0.1 2023年2月26日
1.0.0 2023年2月21日
0.1.0 2023年2月13日

#153 in 进程宏

Download history 806/week @ 2024-04-07 616/week @ 2024-04-14 739/week @ 2024-04-21 613/week @ 2024-04-28 548/week @ 2024-05-05 524/week @ 2024-05-12 463/week @ 2024-05-19 911/week @ 2024-05-26 837/week @ 2024-06-02 873/week @ 2024-06-09 708/week @ 2024-06-16 580/week @ 2024-06-23 1090/week @ 2024-06-30 694/week @ 2024-07-07 995/week @ 2024-07-14 1591/week @ 2024-07-21

每月4,389次下载

MIT/Apache

35KB
695

crates.io Build Status docs.rs

subenum

Subenum是一个简单的进程宏,用于派生子集枚举。它允许在父枚举和子枚举之间进行转换,并将派生到父枚举上的任何特质派生到子枚举上,如果您在父枚举上派生它,则将在父枚举和子枚举之间实现 PartialEq

简单示例

我认为用例子来说明它是最简单的方法

use subenum::subenum;

#[subenum(Edible)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Plant {
    #[subenum(Edible)]
    Basil,
    #[subenum(Edible)]
    Tomato,
    Manzanita,
    Pine,
}

fn main() -> Result<(), EdibleConvertError> {
    let plant = Plant::Tomato;

    // We can convert between them.
    let edible = Edible::try_from(plant)?;
    let _plant2 = Plant::from(edible);

    // We can compare them.
    assert_eq!(plant, edible);

    // We derive anything that's derived on the parent, such as clone.
    let edible2 = edible.clone();

    Ok(())
}

复杂示例

除了简单的枚举和内置特质外,subenum还可以与复杂枚举和第三方属性一起使用。

use subenum::subenum;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AppleType {
    CosmicCrisp,
    Fuji,
    PinkLady,
}

#[subenum(Foo, Tree, Edible, Grass)]
#[derive(Debug, Clone, Copy, PartialEq, strum::Display)]
pub enum Plant<'a, T> {
    #[subenum(Foo)]
    #[strum(serialize = "This is not a plant!")]
    Foo { x: i32, y: i32 },
    #[subenum(Tree, Edible)]
    Apple(AppleType),
    #[subenum(Grass)]
    Bamboo(&'a str),
    #[subenum(Edible)]
    Basil(T),
    #[subenum(Tree)]
    Fir,
    #[subenum(Tree)]
    Pine,
    #[subenum(Edible)]
    Tomato,
    #[subenum(Edible, Grass)]
    Wheat,
}

fn main() -> Result<(), TreeConvertError> {
    let plant: Plant<'_, u32> = Plant::Apple(AppleType::CosmicCrisp);
    let tree = Tree::try_from(plant)?;

    assert_eq!(plant, tree);

    let tree2 = tree.clone();
    assert_eq!(tree2.to_string(), "Apple");

    let foo = Foo::Foo { x: 3, y: 4 };
    assert_eq!(foo.to_string(), "This is not a plant!");

    let edible = Edible::Basil(3);
    let plant = Plant::from(edible);

    assert_eq!(plant.to_string(), "Basil");

    // Can't compare two subenums.
    // assert_ne!(tree2, edible);

    // But we can do some conversion-trickery
    assert_ne!(Plant::from(tree2), Plant::from(edible));

    Ok(())
}

Subenum特定的进程宏

也许你有一个不能 Copy 的枚举,但子枚举可以,你想要派生它

use subenum::subenum;

#[subenum(Bar, Qux(derive(Copy)))]
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Foo {
    #[subenum(Bar)]
    A(String),
    #[subenum(Qux)]
    B,
    #[subenum(Bar, Qux)]
    C(u8),
}

fn main() {
    let b = Qux::B;
    let c = b;
    assert_eq!(b, c);
}

限制

生命周期界限(例如 for<'a, 'b, 'c>)目前不支持。如果您需要这些功能,请提交工单。

功能

  • default - stderror_trait
  • std - 在此进程宏中使用标准库集合和分配器
  • error_trait - 为 ConvertError 类型实现 Error

依赖项

~1.5MB
~36K SLoC