thedes_entity/
monotonic.rs1use std::{collections::HashMap, fmt};
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6#[derive(Debug, Clone, Copy, Error)]
7#[error("Invalid identifier {0}")]
8pub struct InvalidId(pub Id);
9
10#[derive(Debug, Clone, Copy, Error)]
11#[error("Invalid index {index} out of length {len}")]
12pub struct InvalidIndex {
13 pub index: usize,
14 pub len: usize,
15}
16
17#[derive(
18 Debug,
19 Clone,
20 Copy,
21 PartialEq,
22 Eq,
23 PartialOrd,
24 Ord,
25 Hash,
26 Default,
27 Serialize,
28 Deserialize,
29)]
30#[serde(transparent)]
31pub struct Id(u64);
32
33impl fmt::Display for Id {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(f, "{}", self.0)
36 }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct Registry<T> {
41 primary: Vec<(Id, T)>,
42 secondary_pos: HashMap<Id, usize>,
43 secondary_neg: Id,
44}
45
46impl<T> Registry<T> {
47 pub fn new() -> Self {
48 Self {
49 primary: Vec::new(),
50 secondary_pos: HashMap::new(),
51 secondary_neg: Id(0),
52 }
53 }
54
55 pub fn len(&self) -> usize {
56 self.primary.len()
57 }
58
59 pub fn create(&mut self, data: T) -> Id {
60 let id = self.secondary_neg;
61 self.secondary_neg.0 += 1;
62 let index = self.primary.len();
63 self.primary.push((id, data));
64 self.secondary_pos.insert(id, index);
65 id
66 }
67
68 pub fn remove(&mut self, id: Id) -> Option<T> {
69 let index = self.secondary_pos.get(&id).copied()?;
70 let new_index = self.primary.len() - 1;
71 if index != new_index {
72 self.primary.swap(index, new_index);
73 let (id, _) = self.primary[index];
74 self.secondary_pos.insert(id, index);
75 }
76 let (_, item) = self.primary.pop().expect("inconsistent tables");
77 Some(item)
78 }
79
80 pub fn id_to_index(&self, id: Id) -> Result<usize, InvalidId> {
81 self.secondary_pos.get(&id).copied().ok_or(InvalidId(id))
82 }
83
84 pub fn get_by_id(&self, id: Id) -> Result<&T, InvalidId> {
85 let index = self.id_to_index(id)?;
86 Ok(&self.primary[index].1)
87 }
88
89 pub fn get_by_id_mut(&mut self, id: Id) -> Result<&mut T, InvalidId> {
90 let index = self.id_to_index(id)?;
91 Ok(&mut self.primary[index].1)
92 }
93
94 pub fn get_by_index(&self, index: usize) -> Result<(Id, &T), InvalidIndex> {
95 let error = InvalidIndex { index, len: self.primary.len() };
96 let (id, value) = self.primary.get(index).ok_or(error)?;
97 Ok((*id, value))
98 }
99
100 pub fn get_by_index_mut(
101 &mut self,
102 index: usize,
103 ) -> Result<(Id, &mut T), InvalidIndex> {
104 let error = InvalidIndex { index, len: self.primary.len() };
105 let (id, value) = self.primary.get_mut(index).ok_or(error)?;
106 Ok((*id, value))
107 }
108
109 pub fn iter<'a>(
110 &'a self,
111 ) -> impl DoubleEndedIterator<Item = (Id, &'a T)> + 'a + Send + Sync
112 where
113 T: Send + Sync,
114 {
115 self.primary.iter().map(|(id, elem)| (*id, elem))
116 }
117
118 pub fn iter_mut<'a>(
119 &'a mut self,
120 ) -> impl DoubleEndedIterator<Item = (Id, &'a mut T)> + 'a + Send + Sync
121 where
122 T: Send + Sync,
123 {
124 self.primary.iter_mut().map(|(id, elem)| (*id, elem))
125 }
126
127 pub fn into_iter<'a>(
128 self,
129 ) -> impl DoubleEndedIterator<Item = (Id, T)> + 'a + Send + Sync
130 where
131 T: Send + Sync + 'a,
132 {
133 self.primary.into_iter().map(|(id, elem)| (id, elem))
134 }
135}