1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use std::marker::PhantomData; use std::u32::MAX; #[derive(Serialize, Deserialize)] pub struct Id<T> { index: u32, #[serde(skip)] marker: PhantomData<T>, } impl<T> Id<T> { pub fn invalid() -> Self { Self::new(MAX) } pub fn is_invalid(&self) -> bool { self.index == MAX } pub fn is_valid(&self) -> bool { self.index != MAX } fn new(index: u32) -> Self { Self { index, marker: PhantomData } } } impl<T> Copy for Id<T> {} impl<T> Clone for Id<T> { fn clone(&self) -> Self { *self } } impl<T> PartialEq for Id<T> { fn eq(&self, other: &Self) -> bool { self.index == other.index } } impl<T> Eq for Id<T> {} impl<T> From<usize> for Id<T> { fn from(index: usize) -> Self { if index >= MAX as usize { Self::invalid() } else { Self::new(index as u32) } } } impl<T> Into<usize> for Id<T> { fn into(self) -> usize { self.index as usize } }