1use std::fmt;
4use std::hash::{Hash, Hasher};
5use std::marker::PhantomData;
6use std::sync::Arc;
7use uuid::Uuid;
8
9#[derive(Clone)]
13pub struct Id(Arc<Uuid>);
14
15impl Id {
16 pub fn unique() -> Self {
18 let uuid = Uuid::new_v4();
19 Self(Arc::new(uuid))
20 }
21}
22
23impl fmt::Display for Id {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 self.0.as_ref().fmt(f)
26 }
27}
28
29impl fmt::Debug for Id {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 write!(f, "Id({})", self.0)
32 }
33}
34
35impl PartialEq<Self> for Id {
36 fn eq(&self, other: &Self) -> bool {
37 Arc::ptr_eq(&self.0, &other.0)
38 }
39}
40
41impl Eq for Id {}
42
43impl Hash for Id {
44 fn hash<H: Hasher>(&self, state: &mut H) {
45 self.0.as_ref().hash(state);
46 }
47}
48
49pub struct IdOf<T> {
61 id: Id,
62 _origin: PhantomData<T>,
63}
64
65unsafe impl<T> Sync for IdOf<T> {}
66
67impl<T> Clone for IdOf<T> {
68 fn clone(&self) -> Self {
69 Self::new(self.id.clone())
70 }
71}
72
73impl<T> fmt::Display for IdOf<T> {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 fmt::Display::fmt(&self.id, f)
76 }
77}
78
79impl<T> fmt::Debug for IdOf<T> {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 fmt::Debug::fmt(&self.id, f)
82 }
83}
84
85impl<T> IdOf<T> {
86 pub(crate) fn new(id: Id) -> Self {
88 Self {
89 id,
90 _origin: PhantomData,
91 }
92 }
93}
94
95impl<T> PartialEq<Self> for IdOf<T> {
96 fn eq(&self, other: &Self) -> bool {
97 self.id.eq(&other.id)
98 }
99}
100
101impl<T> Eq for IdOf<T> {}
102
103impl<T> Hash for IdOf<T> {
104 fn hash<H: Hasher>(&self, state: &mut H) {
105 self.id.hash(state);
106 }
107}
108
109impl<T> From<IdOf<T>> for Id {
110 fn from(id_of: IdOf<T>) -> Self {
111 id_of.id
112 }
113}
114
115impl<T> AsRef<Id> for IdOf<T> {
116 fn as_ref(&self) -> &Id {
117 &self.id
118 }
119}