indexvec/
lib.rs

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;