unique_id_collection/
lib.rs

1use std::collections::{HashMap, VecDeque};
2
3pub struct UniqueIdCollection<T> {
4    items: HashMap<u8, T>,
5    deleted_ids: VecDeque<u8>,
6    id_counter: u8,
7}
8
9impl<T> UniqueIdCollection<T> {
10    pub fn new() -> Self {
11        UniqueIdCollection {
12            items: HashMap::new(),
13            deleted_ids: VecDeque::new(),
14            id_counter: 0,
15        }
16    }
17
18    pub fn add_item(&mut self, item: T) -> u8 {
19        if let Some(reused_id) = self.deleted_ids.pop_front() {
20            self.items.insert(reused_id, item);
21            reused_id
22        } else {
23            self.id_counter += 1;
24            let new_id = self.id_counter;
25            self.items.insert(new_id, item);
26            new_id
27        }
28    }
29
30    pub fn get_item(&self, id: u8) -> Option<&T> {
31        self.items.get(&id)
32    }
33
34    pub fn get_item_mut(&mut self, id: u8) -> Option<&mut T> {
35        self.items.get_mut(&id)
36    }
37
38    pub fn remove_item(&mut self, id: u8) -> Option<T> {
39        if let Some(removed_item) = self.items.remove(&id) {
40            self.deleted_ids.push_back(id);
41            Some(removed_item)
42        } else {
43            None
44        }
45    }
46
47    pub fn len(&self) -> usize {
48        self.items.len()
49    }
50
51    pub fn is_empty(&self) -> bool {
52        self.items.is_empty()
53    }
54}
55
56impl<T> Default for UniqueIdCollection<T> {
57    fn default() -> Self {
58        Self::new()
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[derive(Debug)]
67    pub struct Something {
68        data: usize,
69    }
70
71    #[test]
72    fn add_item() {
73        let mut collection = UniqueIdCollection::<Something>::new();
74        let item_id = collection.add_item(Something { data: 42 });
75        assert_eq!(item_id, 1);
76
77        let found_item = collection.get_item(item_id).unwrap();
78
79        eprintln!("found item {:?}", found_item);
80
81        assert_eq!(found_item.data, 42);
82    }
83}