1use core::fmt;
5use std::collections::HashMap;
6use std::marker::PhantomData;
7use std::ops::{Index, IndexMut};
8use serde::{Deserialize, Serialize};
9
10pub trait Id: Copy + Clone + Eq + PartialEq + fmt::Debug + Into<u64> + From<u64> {
13 const NONE: Self;
14
15 fn none() -> Self {
16 Self::NONE
17 }
18
19 fn is_none(&self) -> bool {
20 self.eq(&Self::NONE)
21 }
22
23 fn as_u64(&self) -> u64 {
25 (*self).into()
26 }
27
28 fn from_u64(val: u64) -> Self {
30 Self::from(val)
31 }
32}
33
34
35#[macro_export]
38macro_rules! new_id_type {
39 () => {};
41
42 (
44 $(#[$meta:meta])*
45 $vis:vis struct $name:ident;
46 $($rest:tt)*
47 ) => {
48 $(#[$meta])*
50 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51 $vis struct $name(pub u64);
52
53 impl From<u64> for $name {
54 #[inline]
55 fn from(val: u64) -> Self {
56 Self(val)
57 }
58 }
59
60 impl From<$name> for u64 {
61 #[inline]
62 fn from(id: $name) -> Self {
63 id.0
64 }
65 }
66
67 impl $crate::Id for $name {
68 const NONE: Self = Self(0);
69 }
70
71 impl serde::Serialize for $name {
72 #[inline]
73 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: serde::Serializer,
76 {
77 self.0.serialize(serializer)
78 }
79 }
80
81 impl<'de> serde::Deserialize<'de> for $name {
82 #[inline]
83 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
84 where
85 D: serde::Deserializer<'de>,
86 {
87 let val = u64::deserialize(deserializer)?;
88 Ok(Self(val))
89 }
90 }
91
92 $crate::new_id_type!($($rest)*);
93 };
94}
95
96new_id_type!{
97 pub struct DefaultId;
98}
99
100
101#[derive(Debug, Clone)]
104#[derive(Serialize, Deserialize)]
105#[serde(transparent)]
106pub struct IdMap<K: Id, V> {
107 pub(crate) inner: HashMap<u64, V>, #[serde(skip)]
109 max_id: u64, #[serde(skip)]
111 _marker: PhantomData<K>,
112}
113
114impl<V> IdMap<DefaultId, V> {
115 pub fn new() -> Self { Self::with_id_capacity(0) }
117
118 pub fn with_capacity(capacity: usize) -> Self { Self::with_id_capacity(capacity) }
120}
121
122impl<K: Id ,V> Default for IdMap<K, V> {
123 fn default() -> Self {
124 Self::with_id()
125 }
126}
127
128impl<K: Id, V> IdMap<K, V> {
129 pub fn with_id() -> Self {
131 Self {
132 inner: HashMap::new(),
133 max_id: 0,
134 _marker: PhantomData,
135 }
136 }
137
138 pub fn with_id_capacity(capacity: usize) -> Self {
140 Self {
141 inner: HashMap::with_capacity(capacity),
142 max_id: 0,
143 _marker: PhantomData,
144 }
145 }
146
147 pub fn insert(&mut self, value: V) -> K {
149 self.max_id += 1; let id_u64 = self.max_id;
151 self.inner.insert(id_u64, value); K::from_u64(id_u64) }
154
155
156 pub fn insert_with_id(&mut self, id: K, value: V) -> Option<V> {
160 let id_u64 = id.as_u64();
161 if id_u64 > self.max_id {
163 self.max_id = id_u64;
164 }
165 self.inner.insert(id_u64, value)
166 }
167
168 pub fn from_vec(values: Vec<V>) -> (Self, Vec<K>) {
171 let mut map = Self {
172 inner: HashMap::with_capacity(values.len()),
173 max_id: 0,
174 _marker: PhantomData,
175 };
176 let ids = values
177 .into_iter()
178 .map(|val| {
179 map.max_id += 1;
180 let id_u64 = map.max_id;
181 map.inner.insert(id_u64, val);
182 K::from_u64(id_u64)
183 })
184 .collect();
185 (map, ids)
186 }
187
188 pub fn insert_cyclic<F>(&mut self, f: F) -> K
191 where
192 F: FnOnce(K) -> V,
193 {
194 self.max_id += 1;
195 let new_id = K::from_u64(self.max_id);
196 let value = f(new_id);
197 self.inner.insert(self.max_id, value);
198 new_id
199 }
200
201 pub fn get(&self, id: K) -> Option<&V> {
203 self.inner.get(&id.as_u64())
204 }
205
206 pub fn get_mut(&mut self, id: K) -> Option<&mut V> {
208 self.inner.get_mut(&id.as_u64())
209 }
210
211 pub fn remove(&mut self, id: K) -> Option<V> {
213 self.inner.remove(&id.as_u64())
214 }
215
216 pub fn contains_id(&self, id: K) -> bool {
218 self.inner.contains_key(&id.as_u64())
219 }
220
221 pub fn max_id(&self) -> K {
223 K::from_u64(self.max_id)
224 }
225
226 pub fn len(&self) -> usize {
228 self.inner.len()
229 }
230
231 pub fn is_empty(&self) -> bool {
233 self.inner.is_empty()
234 }
235
236 pub fn clear(&mut self) {
238 self.inner.clear();
239 }
240}
241
242impl<K: Id, V> Index<K> for IdMap<K, V> {
244 type Output = V;
245
246 fn index(&self, id: K) -> &Self::Output {
247 self.get(id).expect("invalid IdMap id")
248 }
249}
250
251impl<K: Id, V> IndexMut<K> for IdMap<K, V> {
252 fn index_mut(&mut self, id: K) -> &mut Self::Output {
253 self.get_mut(id).expect("invalid IdMap id")
254 }
255}
256
257#[cfg(test)]
259mod tests {
260 use super::*;
261 use serde_json;
262
263 #[test]
265 fn test_default_id_auto_generate() {
266 let mut map = IdMap::new();
267
268 let id1 = map.insert("hello");
270 let id2 = map.insert("world");
271 let id3 = map.insert("rust");
272
273 assert_eq!(id1, DefaultId(1));
275 assert_eq!(id2, DefaultId(2));
276 assert_eq!(id3, DefaultId(3));
277
278 assert_eq!(map.get(id1), Some(&"hello"));
280 assert_eq!(map[id2], "world");
281 assert_eq!(map.max_id(), DefaultId(3));
282
283 map.remove(id2);
285 assert_eq!(map.max_id(), DefaultId(3));
286 let id4 = map.insert("new value");
287 assert_eq!(id4, DefaultId(4)); assert_eq!(map.len(), 3);
291 map.clear();
292 assert!(map.is_empty());
293 }
294
295 new_id_type! {
297 struct MyId;
298 }
299
300 #[test]
301 fn test_custom_id() {
302 let mut map = IdMap::<MyId, u32>::with_id();
303
304 let id1 = map.insert(42);
305 let id2 = map.insert(100);
306
307 assert_eq!(id1, MyId(1));
308 assert_eq!(id2, MyId(2));
309 assert_eq!(map.get(id1), Some(&42));
310
311 map.remove(id1);
313 assert!(!map.contains_id(id1));
314 }
315
316 #[test]
318 fn test_id_serde() {
319 let id = DefaultId(123456789);
321 let json = serde_json::to_string(&id).unwrap();
322 assert_eq!(json, "123456789"); let id2: DefaultId = serde_json::from_str(&json).unwrap();
324 assert_eq!(id2, id);
325
326 let my_id = MyId(987654321);
328 let json = serde_json::to_string(&my_id).unwrap();
329 let my_id2: MyId = serde_json::from_str(&json).unwrap();
330 assert_eq!(my_id2, my_id);
331 }
332}