1#![feature(unboxed_closures)]
2#![feature(fn_traits)]
3
4mod idx;
5mod idx_vec;
6
7pub use idx::Idx;
8pub use idx_vec::{Enumerated, IndexVec, IntoIdx};
9
10#[cfg(not(feature = "serde"))]
11#[macro_export]
12macro_rules! newtype_index {
13 ($($tt:tt)*) => {
14 $crate::_newtype_index!($($tt)*);
15 };
16}
17
18#[cfg(feature = "serde")]
19#[macro_export]
20macro_rules! newtype_index {
21 ($($tt:tt)*) => {
22 $crate::_newtype_index! {
23 #[derive(serde::Serialize, serde::Deserialize)]
24 #[serde(transparent)]
25 $($tt)*
26 }
27 };
28}
29
30#[doc(hidden)]
31#[macro_export]
32macro_rules! _newtype_index {
33 (
34 $(#[$attrs:meta])*
35 $vis:vis struct $type:ident
36 {
37 $( $const_vis:vis const $constant:ident = $value:expr; )*
38 }
39 ) => {
40 #[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
41 $(#[$attrs])*
42 $vis struct $type {
43 idx: usize,
44 }
45
46 impl $type {
47 $( $const_vis const $constant: $type = Self::const_new($value); )*
48 }
49
50 impl $type {
51 #[allow(unused)]
52 pub const fn const_new(idx: usize) -> Self {
53 Self { idx }
54 }
55 }
56
57 impl Clone for $type {
58 #[inline]
59 fn clone(&self) -> Self {
60 *self
61 }
62 }
63
64 impl $crate::Idx for $type {
65 #[inline]
66 fn new(idx: usize) -> Self {
67 Self { idx }
68 }
69
70 #[inline]
71 fn index(self) -> usize {
72 self.idx
73 }
74 }
75
76 impl ::std::str::FromStr for $type {
77 type Err = ::std::num::ParseIntError;
78
79 fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
80 s.parse::<usize>().map($crate::Idx::new)
81 }
82 }
83 };
84 (
85 $(#[$attrs:meta])*
86 $vis:vis $type:ident
87 ) => {
88 $crate::_newtype_index! {
89 $(#[$attrs])*
90 $vis struct $type {}
91 }
92 };
93}
94
95#[cfg(test)]
96mod tests;