shared_ids/
lib.rs

1use serde::{Deserialize, Serialize};
2use std::{fmt::Debug, hash::Hash, marker::PhantomData};
3
4#[doc(hidden)]
5pub use paste::paste;
6
7#[macro_export]
8macro_rules! id_type {
9    ($vis:vis $name:ident) => {
10        #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
11        #[doc(hidden)]
12        $vis struct $name;
13        impl $crate::IdType for $name {
14            const NAME: &'static str = ::std::stringify!($name);
15        }
16        $crate::paste! {
17            $vis type [< $name Id >] = $crate::Id<$name>;
18        }
19    };
20}
21
22id_type!(pub Client);
23id_type!(pub Request);
24id_type!(pub Replica);
25
26pub trait IdType: Debug + Clone + Copy + Hash + PartialEq + Eq + PartialOrd + Ord {
27    const NAME: &'static str;
28}
29
30#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
31#[repr(transparent)]
32#[serde(transparent, bound = "")]
33pub struct Id<T: IdType> {
34    id: u64,
35    phantom_data: PhantomData<T>,
36}
37
38impl<T: IdType> Id<T> {
39    pub const fn first() -> Self {
40        Self::from_u64(0)
41    }
42
43    pub const fn from_u64(id: u64) -> Self {
44        Self {
45            id,
46            phantom_data: PhantomData,
47        }
48    }
49
50    pub const fn as_u64(&self) -> u64 {
51        self.id
52    }
53
54    pub fn as_mut_u64(&mut self) -> &mut u64 {
55        &mut self.id
56    }
57}
58
59impl<T: IdType> std::fmt::Display for Id<T> {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        write!(f, "{}Id({})", T::NAME, self.id)
62    }
63}
64
65impl<T: IdType> std::fmt::Debug for Id<T> {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "{}Id({})", T::NAME, self.id)
68    }
69}
70
71pub struct IdIter<T: IdType> {
72    next: Id<T>,
73}
74
75impl<T: IdType> Default for IdIter<T> {
76    fn default() -> Self {
77        Self { next: Id::first() }
78    }
79}
80
81impl<T: IdType> Iterator for IdIter<T> {
82    type Item = Id<T>;
83
84    fn next(&mut self) -> Option<Self::Item> {
85        let ret = self.next;
86
87        let id = self.next.as_mut_u64();
88
89        if let Some(next) = id.checked_add(1) {
90            *id = next;
91            Some(ret)
92        } else {
93            None
94        }
95    }
96}