#index #derive #type #usize #boilerplate #typed-index

typed_index_derive

自定义 derive 以轻松创建新的索引类型

3 个版本

使用旧的 Rust 2015

0.1.4 2018年6月19日
0.1.3 2018年6月19日
0.1.2 2018年6月4日
0.1.1 2018年6月3日

#26 in #usize

MIT/Apache

10KB
120

typed_index_derive

Build Status Crates.io API reference

自定义 derive 以轻松创建新的索引类型。

Rust 中的一种常见模式是将对象存储在向量中,并使用整数索引作为处理程序。虽然使用 usize 可以工作,但如果存在多个索引版本,可能会变得令人困惑。为了使每个索引的含义清晰,像 FooIdx(usize) 这样的新类型包装器很有用,但需要相当多的样板代码。这个crate为您生成了样板代码

#[macro_use]
extern crate typed_index_derive;

struct Spam(String);

#[derive(
    // Usual derives for plain old data
    Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash,
    // this crate
    TypedIndex
)]
#[typed_index(Spam)] // index into `&[Spam]`
struct SpamIdx(usize); // could be `u32` instead of `usize`

fn main() {
    let spams = vec![Spam("foo".into()), Spam("bar".into()), Spam("baz".into())];

    // Conversions between `usize` and `SpamIdx`
    let idx: SpamIdx = 1.into();
    assert_eq!(usize::from(idx), 1);

    // We can index `Vec<Spam>` with SpamIdx
    assert_eq!(&spams[idx].0, "bar");

    // However, we can't index `Vec<usize>`
    // vec![1, 2, 3][idx]
    // error: slice indices are of type `usize` or ranges of `usize`

    // You can add/subtract `usize` from an index
    assert_eq!(&spams[idx - 1].0, "foo");

    // The difference between two indices is `usize`
    assert_eq!(idx - idx, 0usize);
}

依赖关系

~2MB
~47K SLoC