Crate typed_index_derive[−][src]
typed_index_derive
A frequent pattern in Rust is to store objects in a vector and use integer indexes
as handlers to them. While using usize
works, it could become confusing if there
are several flavors of indexes. To make the meaning of each index clear the newtype
wrappers like FooIdx(usize)
are useful, but require a fair amount of boilerplate.
This crate derives the boilerplate for you:
#[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` // Similarly to `<[Spam]>::get`, `SpamIdx::get`/`SpamIdx::get_mut` // returns `None` if it's out of bounds. Note that the receiver and // argument are flipped. let oob: SpamIdx = 92.into(); assert!(oob.get(&spams).is_none()); // 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); }
Functions
derive_typed_index |