1use core::fmt;
5use std::collections::HashMap;
6use std::marker::PhantomData;
7use std::ops::{Index, IndexMut};
8
9pub trait Id: Copy + Clone + Eq + PartialEq + fmt::Debug + Into<u64> + From<u64> {
12 fn as_u64(&self) -> u64 {
14 (*self).into()
15 }
16
17 fn from_u64(val: u64) -> Self {
19 Self::from(val)
20 }
21}
22
23
24#[macro_export]
27macro_rules! new_id_type {
28 () => {};
30
31 (
33 $(#[$meta:meta])*
34 $vis:vis struct $name:ident;
35 $($rest:tt)*
36 ) => {
37 $(#[$meta])*
39 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40 $vis struct $name(pub u64);
41
42 impl From<u64> for $name {
43 #[inline]
44 fn from(val: u64) -> Self {
45 Self(val)
46 }
47 }
48
49 impl From<$name> for u64 {
50 #[inline]
51 fn from(id: $name) -> Self {
52 id.0
53 }
54 }
55
56 impl $crate::Id for $name {}
57
58 impl serde::Serialize for $name {
59 #[inline]
60 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
61 where
62 S: serde::Serializer,
63 {
64 self.0.serialize(serializer)
65 }
66 }
67
68 impl<'de> serde::Deserialize<'de> for $name {
69 #[inline]
70 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
71 where
72 D: serde::Deserializer<'de>,
73 {
74 let val = u64::deserialize(deserializer)?;
75 Ok(Self(val))
76 }
77 }
78
79 $crate::new_id_type!($($rest)*);
80 };
81}
82
83new_id_type!{
84 pub struct DefaultId;
85}
86
87
88#[derive(Debug, Clone)]
91pub struct IdMap<K: Id, V> {
92 pub(crate) inner: HashMap<u64, V>, max_id: u64, _marker: PhantomData<K>,
95}
96
97impl<V> IdMap<DefaultId, V> {
98 pub fn new() -> Self { Self::with_id_capacity(0) }
100
101 pub fn with_capacity(capacity: usize) -> Self { Self::with_id_capacity(capacity) }
103}
104
105impl<K: Id, V> IdMap<K, V> {
106 pub fn with_id() -> Self {
108 Self {
109 inner: HashMap::new(),
110 max_id: 0,
111 _marker: PhantomData,
112 }
113 }
114
115 pub fn with_id_capacity(capacity: usize) -> Self {
117 Self {
118 inner: HashMap::with_capacity(capacity),
119 max_id: 0,
120 _marker: PhantomData,
121 }
122 }
123
124 pub fn insert(&mut self, value: V) -> K {
126 self.max_id += 1; let id_u64 = self.max_id;
128 self.inner.insert(id_u64, value); K::from_u64(id_u64) }
131
132
133 pub fn insert_with_id(&mut self, id: K, value: V) -> Option<V> {
137 let id_u64 = id.as_u64();
138 if id_u64 > self.max_id {
140 self.max_id = id_u64;
141 }
142 self.inner.insert(id_u64, value)
143 }
144
145 pub fn from_vec(values: Vec<V>) -> (Self, Vec<K>) {
148 let mut map = Self {
149 inner: HashMap::with_capacity(values.len()),
150 max_id: 0,
151 _marker: PhantomData,
152 };
153 let ids = values
154 .into_iter()
155 .map(|val| {
156 map.max_id += 1;
157 let id_u64 = map.max_id;
158 map.inner.insert(id_u64, val);
159 K::from_u64(id_u64)
160 })
161 .collect();
162 (map, ids)
163 }
164
165 pub fn insert_cyclic<F>(&mut self, f: F) -> K
168 where
169 F: FnOnce(K) -> V,
170 {
171 self.max_id += 1;
172 let new_id = K::from_u64(self.max_id);
173 let value = f(new_id);
174 self.inner.insert(self.max_id, value);
175 new_id
176 }
177
178 pub fn get(&self, id: K) -> Option<&V> {
180 self.inner.get(&id.as_u64())
181 }
182
183 pub fn get_mut(&mut self, id: K) -> Option<&mut V> {
185 self.inner.get_mut(&id.as_u64())
186 }
187
188 pub fn remove(&mut self, id: K) -> Option<V> {
190 self.inner.remove(&id.as_u64())
191 }
192
193 pub fn contains_id(&self, id: K) -> bool {
195 self.inner.contains_key(&id.as_u64())
196 }
197
198 pub fn max_id(&self) -> K {
200 K::from_u64(self.max_id)
201 }
202
203 pub fn len(&self) -> usize {
205 self.inner.len()
206 }
207
208 pub fn is_empty(&self) -> bool {
210 self.inner.is_empty()
211 }
212
213 pub fn clear(&mut self) {
215 self.inner.clear();
216 }
217}
218
219impl<K: Id, V> Index<K> for IdMap<K, V> {
221 type Output = V;
222
223 fn index(&self, id: K) -> &Self::Output {
224 self.get(id).expect("invalid IdMap id")
225 }
226}
227
228impl<K: Id, V> IndexMut<K> for IdMap<K, V> {
229 fn index_mut(&mut self, id: K) -> &mut Self::Output {
230 self.get_mut(id).expect("invalid IdMap id")
231 }
232}
233
234#[cfg(test)]
236mod tests {
237 use super::*;
238 use serde_json;
239
240 #[test]
242 fn test_default_id_auto_generate() {
243 let mut map = IdMap::new();
244
245 let id1 = map.insert("hello");
247 let id2 = map.insert("world");
248 let id3 = map.insert("rust");
249
250 assert_eq!(id1, DefaultId(1));
252 assert_eq!(id2, DefaultId(2));
253 assert_eq!(id3, DefaultId(3));
254
255 assert_eq!(map.get(id1), Some(&"hello"));
257 assert_eq!(map[id2], "world");
258 assert_eq!(map.max_id(), DefaultId(3));
259
260 map.remove(id2);
262 assert_eq!(map.max_id(), DefaultId(3));
263 let id4 = map.insert("new value");
264 assert_eq!(id4, DefaultId(4)); assert_eq!(map.len(), 3);
268 map.clear();
269 assert!(map.is_empty());
270 }
271
272 new_id_type! {
274 struct MyId;
275 }
276
277 #[test]
278 fn test_custom_id() {
279 let mut map = IdMap::<MyId, u32>::with_id();
280
281 let id1 = map.insert(42);
282 let id2 = map.insert(100);
283
284 assert_eq!(id1, MyId(1));
285 assert_eq!(id2, MyId(2));
286 assert_eq!(map.get(id1), Some(&42));
287
288 map.remove(id1);
290 assert!(!map.contains_id(id1));
291 }
292
293 #[test]
295 fn test_id_serde() {
296 let id = DefaultId(123456789);
298 let json = serde_json::to_string(&id).unwrap();
299 assert_eq!(json, "123456789"); let id2: DefaultId = serde_json::from_str(&json).unwrap();
301 assert_eq!(id2, id);
302
303 let my_id = MyId(987654321);
305 let json = serde_json::to_string(&my_id).unwrap();
306 let my_id2: MyId = serde_json::from_str(&json).unwrap();
307 assert_eq!(my_id2, my_id);
308 }
309}