#index #enums #macro #traits #deriving #pat #index-mut

过程宏 impl_index

用于推导Index特质的宏

1个稳定版本

1.0.0 2023年11月22日

#802过程宏

Apache-2.0

16KB
236

用于推导Index & IndexMut实现的宏。

MASTER CI status crates.io badge docs.rs badge dependencies badge

基本用法

// Derive only Index
index!(Struct by Enum => Output:
  Variant1 => field1,
  Variant2 => field2,
);

// Derive Index and IndexMut
index!(Struct by Enum => mut Output:
  Variant1 => field1,
  Variant2 => field2,
);

// Match/get by pattern
index!(Struct by Enum => Output:
  pat Enum::Variant(Foo::Bar) => field1,
  pat Enum::Index(idx) => pat field2[idx],
);

示例

use impl_index::index;

#[derive(Default)]
struct Struct {
    a: u8,
    arr: [u8; 10],
    thing_1: u8,
    thing_2: u8,
}

enum Enum {
    A,
    Arr(usize),
    Thing(Thing),
}

enum Thing {
    One,
    Two,
}

index!(Struct by Enum => mut u8:
    A => a,
    pat Enum::Arr(idx) if idx < 10 => pat arr[idx],
    pat Enum::Thing(Thing::One) => thing_1,
    pat _ => thing_2,
);

let mut s = Struct::default();

s[Enum::A] = 1;

for idx in 0u8..10 {
    s[Enum::Arr(idx.into())] = idx * 10;
}

s[Enum::Thing(Thing::One)] = 200;
s[Enum::Thing(Thing::Two)] = 201;

assert_eq!(s[Enum::A], 1, "A");
for idx in 0u8..10 {
    assert_eq!(s[Enum::Arr(idx.into())], idx * 10, "Arr({})", idx);
}
assert_eq!(s[Enum::Thing(Thing::One)], 200, "Thing(One)");
assert_eq!(s[Enum::Thing(Thing::Two)], 201, "Thing(Two)");

生成输出

#[automatically_derived]
impl ::core::ops::Index<Enum> for Struct {
    type Output = u8;
    fn index(&self, index_macro_derived_index_input: Enum) -> &Self::Output {
        match index_macro_derived_index_input {
            Enum::A => &self.a,
            Enum::Arr(idx) if idx < 10 => &self.arr[idx],
            Enum::Thing(Thing::One) => &self.thing_1,
            _ => &self.thing_2,
        }
    }
}
#[automatically_derived]
impl ::core::ops::IndexMut<Enum> for Struct {
    fn index_mut(&mut self, index_macro_derived_index_input: Enum) -> &mut Self::Output {
        match index_macro_derived_index_input {
            Enum::A => &mut self.a,
            Enum::Arr(idx) if idx < 10 => &mut self.arr[idx],
            Enum::Thing(Thing::One) => &mut self.thing_1,
            _ => &mut self.thing_2,
        }
    }
}

不生成IndexMut的示例

instance[Idx::Foo] = 1;上编译会失败

struct Struct {
  foo: usize,
}

enum Idx {
  Foo,
}

index!(Struct by Idx => usize: Foo => foo);

let mut instance = Struct { foo: 0 };
instance[Idx::Foo] = 1;

依赖

~275–720KB
~17K SLoC