1use core::fmt;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use std::collections::HashMap;
7use std::marker::PhantomData;
8use std::ops::{Index, IndexMut};
9
10pub trait Id: Copy + Clone + Eq + PartialEq + fmt::Debug + Into<u64> + From<u64> {
13 fn as_u64(&self) -> u64 {
15 (*self).into()
16 }
17
18 fn from_u64(val: u64) -> Self {
20 Self::from(val)
21 }
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub struct DefaultId(pub u64);
27
28impl From<u64> for DefaultId {
30 #[inline]
31 fn from(val: u64) -> Self {
32 Self(val)
33 }
34}
35
36impl From<DefaultId> for u64 {
37 #[inline]
38 fn from(id: DefaultId) -> Self {
39 id.0
40 }
41}
42
43impl Id for DefaultId {}
44
45impl Serialize for DefaultId {
47 #[inline]
48 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: Serializer,
51 {
52 self.0.serialize(serializer)
54 }
55}
56
57impl<'de> Deserialize<'de> for DefaultId {
58 #[inline]
59 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60 where
61 D: Deserializer<'de>,
62 {
63 let val = u64::deserialize(deserializer)?;
65 Ok(Self(val))
66 }
67}
68
69#[macro_export]
72macro_rules! new_id_type {
73 ($(#[$meta:meta])* struct $name:ident; ) => {
74 $(#[$meta])*
75 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76 pub struct $name(pub u64);
77
78 impl From<u64> for $name {
80 #[inline]
81 fn from(val: u64) -> Self {
82 Self(val)
83 }
84 }
85
86 impl From<$name> for u64 {
87 #[inline]
88 fn from(id: $name) -> Self {
89 id.0
90 }
91 }
92
93 impl $crate::Id for $name {}
95
96 impl serde::Serialize for $name {
98 #[inline]
99 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
100 where
101 S: serde::Serializer,
102 {
103 self.0.serialize(serializer)
104 }
105 }
106
107 impl<'de> serde::Deserialize<'de> for $name {
108 #[inline]
109 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
110 where
111 D: serde::Deserializer<'de>,
112 {
113 let val = u64::deserialize(deserializer)?;
114 Ok(Self(val))
115 }
116 }
117 };
118}
119
120#[derive(Debug, Clone)]
123pub struct IdMap<K: Id, V> {
124 pub(crate) inner: HashMap<u64, V>, max_id: u64, _marker: PhantomData<K>,
127}
128
129impl<V> IdMap<DefaultId, V> {
130 pub fn new() -> Self { Self::with_id_capacity(0) }
132
133 pub fn with_capacity(capacity: usize) -> Self { Self::with_id_capacity(capacity) }
135}
136
137impl<K: Id, V> IdMap<K, V> {
138 pub fn with_id() -> Self {
140 Self {
141 inner: HashMap::new(),
142 max_id: 0,
143 _marker: PhantomData,
144 }
145 }
146
147 pub fn with_id_capacity(capacity: usize) -> Self {
149 Self {
150 inner: HashMap::with_capacity(capacity),
151 max_id: 0,
152 _marker: PhantomData,
153 }
154 }
155
156 pub fn insert(&mut self, value: V) -> K {
158 self.max_id += 1; let id_u64 = self.max_id;
160 self.inner.insert(id_u64, value); K::from_u64(id_u64) }
163
164
165 pub fn insert_with_id(&mut self, id: K, value: V) -> Option<V> {
169 let id_u64 = id.as_u64();
170 if id_u64 > self.max_id {
172 self.max_id = id_u64;
173 }
174 self.inner.insert(id_u64, value)
175 }
176
177 pub fn from_vec(values: Vec<V>) -> (Self, Vec<K>) {
180 let mut map = Self {
181 inner: HashMap::with_capacity(values.len()),
182 max_id: 0,
183 _marker: PhantomData,
184 };
185 let ids = values
186 .into_iter()
187 .map(|val| {
188 map.max_id += 1;
189 let id_u64 = map.max_id;
190 map.inner.insert(id_u64, val);
191 K::from_u64(id_u64)
192 })
193 .collect();
194 (map, ids)
195 }
196
197 pub fn insert_cyclic<F>(&mut self, f: F) -> K
200 where
201 F: FnOnce(K) -> V,
202 {
203 self.max_id += 1;
204 let new_id = K::from_u64(self.max_id);
205 let value = f(new_id);
206 self.inner.insert(self.max_id, value);
207 new_id
208 }
209
210 pub fn get(&self, id: K) -> Option<&V> {
212 self.inner.get(&id.as_u64())
213 }
214
215 pub fn get_mut(&mut self, id: K) -> Option<&mut V> {
217 self.inner.get_mut(&id.as_u64())
218 }
219
220 pub fn remove(&mut self, id: K) -> Option<V> {
222 self.inner.remove(&id.as_u64())
223 }
224
225 pub fn contains_id(&self, id: K) -> bool {
227 self.inner.contains_key(&id.as_u64())
228 }
229
230 pub fn max_id(&self) -> K {
232 K::from_u64(self.max_id)
233 }
234
235 pub fn len(&self) -> usize {
237 self.inner.len()
238 }
239
240 pub fn is_empty(&self) -> bool {
242 self.inner.is_empty()
243 }
244
245 pub fn clear(&mut self) {
247 self.inner.clear();
248 }
249}
250
251impl<K: Id, V> Index<K> for IdMap<K, V> {
253 type Output = V;
254
255 fn index(&self, id: K) -> &Self::Output {
256 self.get(id).expect("invalid IdMap id")
257 }
258}
259
260impl<K: Id, V> IndexMut<K> for IdMap<K, V> {
261 fn index_mut(&mut self, id: K) -> &mut Self::Output {
262 self.get_mut(id).expect("invalid IdMap id")
263 }
264}
265
266#[cfg(test)]
268mod tests {
269 use super::*;
270 use serde_json;
271
272 #[test]
274 fn test_default_id_auto_generate() {
275 let mut map = IdMap::new();
276
277 let id1 = map.insert("hello");
279 let id2 = map.insert("world");
280 let id3 = map.insert("rust");
281
282 assert_eq!(id1, DefaultId(1));
284 assert_eq!(id2, DefaultId(2));
285 assert_eq!(id3, DefaultId(3));
286
287 assert_eq!(map.get(id1), Some(&"hello"));
289 assert_eq!(map[id2], "world");
290 assert_eq!(map.max_id(), DefaultId(3));
291
292 map.remove(id2);
294 assert_eq!(map.max_id(), DefaultId(3));
295 let id4 = map.insert("new value");
296 assert_eq!(id4, DefaultId(4)); assert_eq!(map.len(), 3);
300 map.clear();
301 assert!(map.is_empty());
302 }
303
304 new_id_type! {
306 struct MyId;
307 }
308
309 #[test]
310 fn test_custom_id() {
311 let mut map = IdMap::<MyId, u32>::with_id();
312
313 let id1 = map.insert(42);
314 let id2 = map.insert(100);
315
316 assert_eq!(id1, MyId(1));
317 assert_eq!(id2, MyId(2));
318 assert_eq!(map.get(id1), Some(&42));
319
320 map.remove(id1);
322 assert!(!map.contains_id(id1));
323 }
324
325 #[test]
327 fn test_id_serde() {
328 let id = DefaultId(123456789);
330 let json = serde_json::to_string(&id).unwrap();
331 assert_eq!(json, "123456789"); let id2: DefaultId = serde_json::from_str(&json).unwrap();
333 assert_eq!(id2, id);
334
335 let my_id = MyId(987654321);
337 let json = serde_json::to_string(&my_id).unwrap();
338 let my_id2: MyId = serde_json::from_str(&json).unwrap();
339 assert_eq!(my_id2, my_id);
340 }
341}