hydro_lang/location/
member_id.rs1use std::fmt::{Debug, Display};
2use std::hash::Hash;
3use std::marker::PhantomData;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Deserialize, Serialize, Debug)]
8pub enum TaglessMemberId {
9 Legacy { raw_id: u32 },
10 Docker { container_name: String },
11}
12
13impl TaglessMemberId {
14 pub fn from_raw_id(raw_id: u32) -> Self {
15 Self::Legacy { raw_id }
16 }
17
18 pub fn from_container_name(container_name: impl ToString) -> Self {
19 Self::Docker {
20 container_name: container_name.to_string(),
21 }
22 }
23
24 pub fn get_raw_id(&self) -> u32 {
25 match self {
26 TaglessMemberId::Legacy { raw_id } => *raw_id,
27 _ => panic!(),
28 }
29 }
30
31 pub fn get_container_name(&self) -> String {
32 match &self {
33 TaglessMemberId::Docker { container_name } => container_name.clone(),
34 _ => panic!(),
35 }
36 }
37}
38
39impl Hash for TaglessMemberId {
40 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
41 match self {
42 TaglessMemberId::Legacy { raw_id } => raw_id.hash(state),
43 TaglessMemberId::Docker { container_name } => container_name.hash(state),
44 }
45 }
46}
47
48impl PartialEq for TaglessMemberId {
49 fn eq(&self, other: &Self) -> bool {
50 match (self, other) {
51 (
52 TaglessMemberId::Legacy { raw_id },
53 TaglessMemberId::Legacy {
54 raw_id: other_raw_id,
55 },
56 ) => raw_id == other_raw_id,
57 (
58 TaglessMemberId::Docker { container_name },
59 TaglessMemberId::Docker {
60 container_name: other_container_name,
61 },
62 ) => container_name == other_container_name,
63 _ => unreachable!(),
64 }
65 }
66}
67
68impl Eq for TaglessMemberId {}
69
70impl PartialOrd for TaglessMemberId {
71 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
72 Some(self.cmp(other))
73 }
74}
75
76impl Ord for TaglessMemberId {
77 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
79 match (self, other) {
80 (
81 TaglessMemberId::Legacy { raw_id },
82 TaglessMemberId::Legacy {
83 raw_id: other_raw_id,
84 },
85 ) => raw_id.cmp(other_raw_id),
86 (
87 TaglessMemberId::Docker { container_name },
88 TaglessMemberId::Docker {
89 container_name: other_container_name,
90 },
91 ) => container_name.cmp(other_container_name),
92 _ => unreachable!(),
93 }
94 }
95}
96
97#[repr(transparent)]
98pub struct MemberId<Tag> {
99 inner: TaglessMemberId,
100 _phantom: PhantomData<Tag>,
101}
102
103impl<Tag> MemberId<Tag> {
104 pub fn into_tagless(self) -> TaglessMemberId {
105 self.inner
106 }
107
108 pub fn from_tagless(inner: TaglessMemberId) -> Self {
109 Self {
110 inner,
111 _phantom: Default::default(),
112 }
113 }
114
115 pub fn from_raw_id(raw_id: u32) -> Self {
116 Self {
117 inner: TaglessMemberId::from_raw_id(raw_id),
118 _phantom: Default::default(),
119 }
120 }
121
122 pub fn get_raw_id(&self) -> u32 {
123 self.inner.get_raw_id()
124 }
125}
126
127impl<Tag> Debug for MemberId<Tag> {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 Display::fmt(self, f)
130 }
131}
132
133impl<Tag> Display for MemberId<Tag> {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 match &self.inner {
136 TaglessMemberId::Legacy { raw_id, .. } => {
137 write!(
138 f,
139 "MemberId::<{}>({})",
140 std::any::type_name::<Tag>(),
141 raw_id
142 )
143 }
144 TaglessMemberId::Docker { container_name, .. } => {
145 write!(
146 f,
147 "MemberId::<{}>(\"{}\")",
148 std::any::type_name::<Tag>(),
149 container_name
150 )
151 }
152 }
153 }
154}
155
156impl<Tag> Clone for MemberId<Tag> {
157 fn clone(&self) -> Self {
158 Self {
159 inner: self.inner.clone(),
160 _phantom: Default::default(),
161 }
162 }
163}
164
165impl<Tag> Serialize for MemberId<Tag> {
166 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
167 where
168 S: serde::Serializer,
169 {
170 self.inner.serialize(serializer)
171 }
172}
173
174impl<'a, Tag> Deserialize<'a> for MemberId<Tag> {
175 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
176 where
177 D: serde::Deserializer<'a>,
178 {
179 Ok(Self::from_tagless(TaglessMemberId::deserialize(
180 deserializer,
181 )?))
182 }
183}
184
185impl<Tag> PartialOrd for MemberId<Tag> {
186 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
187 Some(self.cmp(other))
188 }
189}
190
191impl<Tag> Ord for MemberId<Tag> {
192 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
193 self.inner.cmp(&other.inner)
194 }
195}
196
197impl<Tag> PartialEq for MemberId<Tag> {
198 fn eq(&self, other: &Self) -> bool {
199 self.inner == other.inner
200 }
201}
202
203impl<Tag> Eq for MemberId<Tag> {}
204
205impl<Tag> Hash for MemberId<Tag> {
206 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
207 self.inner.hash(state);
208 std::any::type_name::<Tag>().hash(state); }
210}