### 內建取得列舉變體「序數」的作法

```enum Mode {
Mode1,
Mode2,
Mode3,
}

fn main() {
assert_eq!(2, Mode::Mode3 as u8);
}```

```enum Mode {
Mode1,
Mode2,
Mode3,
}

struct Config {
mode: Mode
}

fn foo(m: &Mode) {
assert_eq!(2, m as u8);
}

fn main() {
let config = Config {
mode: Mode::Mode3
};

foo(&config.mode);
}```

```#[derive(Clone)]
enum Mode {
Mode1,
Mode2,
Mode3,
}

struct Config {
mode: Mode
}

fn foo(m: Mode) {
assert_eq!(2, m as u8);
}

fn main() {
let config = Config {
mode: Mode::Mode3
};

foo(config.mode.clone());
}```

### Enum Ordinalize

「Enum Ordinalize」是筆者開發的程序式巨集套件，可以讓列舉實作`Oridinal`特性，使其擁有`from_ordinal_unsafe``from_ordinal`關聯函數，以及`ordinal`方法，還有`VARIANT_COUNT``VARIANTS``VALUES`常數。

Crates.io

Cargo.toml

enum-ordinalize = "*"

#### 使用方法

```use enum_ordinalize::Ordinalize;

#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Zero,
One,
Two,
}

assert_eq!(3, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two], MyEnum::VARIANTS);
assert_eq!([0i8, 1i8, 2i8], MyEnum::VALUES);

assert_eq!(0i8, MyEnum::Zero.ordinal());
assert_eq!(1i8, MyEnum::One.ordinal());
assert_eq!(2i8, MyEnum::Two.ordinal());

assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i8));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i8));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i8));

assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i8) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i8) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i8) });```

#### 「序數」的大小

```use enum_ordinalize::Ordinalize;

#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Zero,
One,
Two,
Thousand = 1000,
}

assert_eq!(4, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two, MyEnum::Thousand], MyEnum::VARIANTS);
assert_eq!([0i16, 1i16, 2i16, 1000i16], MyEnum::VALUES);

assert_eq!(0i16, MyEnum::Zero.ordinal());
assert_eq!(1i16, MyEnum::One.ordinal());
assert_eq!(2i16, MyEnum::Two.ordinal());

assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i16));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i16));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i16));

assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i16) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i16) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i16) });```

```use enum_ordinalize::Ordinalize;

#[derive(Debug, PartialEq, Eq, Ordinalize)]
#[repr(usize)]
enum MyEnum {
Zero,
One,
Two,
Thousand = 1000,
}

assert_eq!(4, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two, MyEnum::Thousand], MyEnum::VARIANTS);
assert_eq!([0usize, 1usize, 2usize, 1000usize], MyEnum::VALUES);

assert_eq!(0usize, MyEnum::Zero.ordinal());
assert_eq!(1usize, MyEnum::One.ordinal());
assert_eq!(2usize, MyEnum::Two.ordinal());

assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0usize));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1usize));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2usize));

assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0usize) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1usize) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2usize) });```

#### 好用的自動累進

```use enum_ordinalize::Ordinalize;

#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Two   = 2,
Three,
Four,
Eight = 8,
Nine,
NegativeTen = -10,
NegativeNine,
}

assert_eq!(7, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Two, MyEnum::Three, MyEnum::Four, MyEnum::Eight, MyEnum::Nine, MyEnum::NegativeTen, MyEnum::NegativeNine], MyEnum::VARIANTS);
assert_eq!([2i8, 3i8, 4i8, 8i8, 9i8, -10i8, -9i8], MyEnum::VALUES);

assert_eq!(4i8, MyEnum::Four.ordinal());
assert_eq!(9i8, MyEnum::Nine.ordinal());
assert_eq!(-9i8, MyEnum::NegativeNine.ordinal());

assert_eq!(Some(MyEnum::Four), MyEnum::from_ordinal(4i8));
assert_eq!(Some(MyEnum::Nine), MyEnum::from_ordinal(9i8));
assert_eq!(Some(MyEnum::NegativeNine), MyEnum::from_ordinal(-9i8));

assert_eq!(MyEnum::Four, unsafe { MyEnum::from_ordinal_unsafe(4i8) });
assert_eq!(MyEnum::Nine, unsafe { MyEnum::from_ordinal_unsafe(9i8) });
assert_eq!(MyEnum::NegativeNine, unsafe { MyEnum::from_ordinal_unsafe(-9i8) });```

#### 在列舉本身實作功能

```use enum_ordinalize::Ordinalize;

#[derive(Debug, PartialEq, Eq, Ordinalize)]
#[ordinalize(impl_trait = false)]
#[ordinalize(variant_count(pub const VARIANT_COUNT, doc = "The count of variants."))]
#[ordinalize(variants(pub const VARIANTS, doc = "List of this enum's variants."))]
#[ordinalize(values(pub const VALUES, doc = "List of values for all variants of this enum."))]
#[ordinalize(ordinal(pub const fn ordinal, doc = "Retrieve the integer number of this variant."))]
#[ordinalize(from_ordinal(pub const fn from_ordinal, doc = "Obtain a variant based on an integer number."))]
#[ordinalize(from_ordinal_unsafe(
pub const fn from_ordinal_unsafe,
doc = "Obtain a variant based on an integer number.",
doc = "# Safety",
doc = "You have to ensure that the input integer number can correspond to a variant on your own.",
))]
enum MyEnum {
A,
B,
}

assert_eq!(2, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::A, MyEnum::B], MyEnum::VARIANTS);
assert_eq!([0i8, 1i8], MyEnum::VALUES);

assert_eq!(0i8, MyEnum::A.ordinal());
assert_eq!(1i8, MyEnum::B.ordinal());

assert_eq!(Some(MyEnum::A), MyEnum::from_ordinal(0i8));
assert_eq!(Some(MyEnum::B), MyEnum::from_ordinal(1i8));

assert_eq!(MyEnum::A, unsafe { MyEnum::from_ordinal_unsafe(0i8) });
assert_eq!(MyEnum::B, unsafe { MyEnum::from_ordinal_unsafe(1i8) });```