batadase_index/
lib.rs

1use std::marker::PhantomData;
2use shrinkwraprs::Shrinkwrap;
3
4#[derive(serde::Serialize, serde::Deserialize, Shrinkwrap)]
5#[serde(transparent)]
6pub struct Index<T>(#[shrinkwrap(main_field)] u64, #[serde(skip)] PhantomData<T>);
7
8#[derive(rkyv::Portable)]
9#[repr(transparent)]
10pub struct ArchivedIndex<T>(<u64 as rkyv::Archive>::Archived, PhantomData<T>);
11
12impl<T> Index<T> {
13	pub fn into<Y>(self) -> Index<Y> {
14		u64::from(self).into()
15	}
16}
17
18impl<T> rkyv::Archive for Index<T> {
19	type Archived = ArchivedIndex<T>;
20	type Resolver = ();
21
22	#[inline]
23	fn resolve(&self, (): (), out: rkyv::Place<Self::Archived>) {
24		unsafe { out.write_unchecked(ArchivedIndex(<u64 as rkyv::Archive>::Archived::from_native(self.0), PhantomData)) };
25	}
26}
27
28impl<D: rkyv::rancor::Fallible + ?Sized, T> rkyv::Deserialize<Index<T>, D> for ArchivedIndex<T> {
29	#[inline]
30	fn deserialize(&self, deserializer: &mut D) -> Result<Index<T>, D::Error> {
31		Ok(Index(rkyv::Deserialize::deserialize(&self.0, deserializer)?, PhantomData))
32	}
33}
34
35impl<S: rkyv::rancor::Fallible + ?Sized, T> rkyv::Serialize<S> for Index<T> {
36	#[inline]
37	fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
38		rkyv::Serialize::serialize(&self.0, serializer)
39	}
40}
41
42impl<T> std::fmt::Debug for Index<T> {
43	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Index<{}>({})", std::any::type_name::<T>(), self.0) }
44}
45
46impl<T> From<Index<T>> for usize {
47	fn from(value: Index<T>) -> Self { value.0 as usize }
48}
49
50impl<T> From<Index<T>> for u64 {
51	fn from(value: Index<T>) -> Self { value.0 }
52}
53
54impl<T> From<u64> for Index<T> {
55	fn from(value: u64) -> Self { Self(value, PhantomData) }
56}
57
58impl<T> From<usize> for Index<T> {
59	fn from(value: usize) -> Self { Self(value as u64, PhantomData) }
60}
61
62impl<T> From<u32> for Index<T> {
63	fn from(value: u32) -> Self { Self(u64::from(value), PhantomData) }
64}
65
66impl<T> Clone for Index<T> {
67	fn clone(&self) -> Self { *self }
68}
69
70impl<T> PartialEq for Index<T> {
71	fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
72}
73
74impl<T> Eq for Index<T> {}
75
76impl<T> std::hash::Hash for Index<T> {
77	fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.0.hash(state); }
78}
79
80impl<T> Copy for Index<T> {}
81
82impl<T> std::fmt::Display for Index<T> {
83	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { <Self as std::fmt::Debug>::fmt(self, f) }
84}
85
86impl<T> std::cmp::PartialOrd for Index<T> {
87	fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) }
88}
89
90impl<T> std::cmp::Ord for Index<T> {
91	fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.0.cmp(&other.0) }
92}
93
94impl<T> Default for Index<T> {
95	fn default() -> Self { Self(0, PhantomData) }
96}