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