1use crate::oid::Oid;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
50pub struct OidTable<V> {
51 entries: Vec<(Oid, V)>,
53}
54
55impl<V> OidTable<V> {
56 #[must_use]
58 pub fn new() -> Self {
59 Self {
60 entries: Vec::new(),
61 }
62 }
63
64 #[must_use]
66 pub fn with_capacity(capacity: usize) -> Self {
67 Self {
68 entries: Vec::with_capacity(capacity),
69 }
70 }
71
72 pub fn insert(&mut self, oid: Oid, value: V) {
76 match self.entries.binary_search_by(|(o, _)| o.cmp(&oid)) {
77 Ok(idx) => self.entries[idx].1 = value,
78 Err(idx) => self.entries.insert(idx, (oid, value)),
79 }
80 }
81
82 pub fn remove(&mut self, oid: &Oid) -> Option<V> {
86 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
87 Ok(idx) => Some(self.entries.remove(idx).1),
88 Err(_) => None,
89 }
90 }
91
92 #[must_use]
94 pub fn get(&self, oid: &Oid) -> Option<&V> {
95 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
96 Ok(idx) => Some(&self.entries[idx].1),
97 Err(_) => None,
98 }
99 }
100
101 #[must_use]
105 pub fn get_next(&self, oid: &Oid) -> Option<(&Oid, &V)> {
106 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
107 Ok(idx) => {
108 self.entries.get(idx + 1).map(|(o, v)| (o, v))
110 }
111 Err(idx) => {
112 self.entries.get(idx).map(|(o, v)| (o, v))
114 }
115 }
116 }
117
118 #[must_use]
120 pub fn len(&self) -> usize {
121 self.entries.len()
122 }
123
124 #[must_use]
126 pub fn is_empty(&self) -> bool {
127 self.entries.is_empty()
128 }
129
130 pub fn clear(&mut self) {
132 self.entries.clear();
133 }
134
135 pub fn iter(&self) -> impl Iterator<Item = (&Oid, &V)> {
137 self.entries.iter().map(|(o, v)| (o, v))
138 }
139}
140
141impl<V> Default for OidTable<V> {
142 fn default() -> Self {
143 Self::new()
144 }
145}
146
147impl<'a, V> IntoIterator for &'a OidTable<V> {
148 type Item = (&'a Oid, &'a V);
149 type IntoIter =
150 std::iter::Map<std::slice::Iter<'a, (Oid, V)>, fn(&'a (Oid, V)) -> (&'a Oid, &'a V)>;
151
152 fn into_iter(self) -> Self::IntoIter {
153 self.entries.iter().map(|(o, v)| (o, v))
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160 use crate::oid;
161
162 #[test]
163 fn test_oid_table_insert_and_get() {
164 let mut table: OidTable<i32> = OidTable::new();
165
166 table.insert(oid!(1, 3, 6, 1, 2), 100);
167 table.insert(oid!(1, 3, 6, 1, 1), 50);
168 table.insert(oid!(1, 3, 6, 1, 3), 150);
169
170 assert_eq!(table.get(&oid!(1, 3, 6, 1, 1)), Some(&50));
172 assert_eq!(table.get(&oid!(1, 3, 6, 1, 2)), Some(&100));
173 assert_eq!(table.get(&oid!(1, 3, 6, 1, 3)), Some(&150));
174 assert_eq!(table.get(&oid!(1, 3, 6, 1, 4)), None);
175 }
176
177 #[test]
178 fn test_oid_table_update_existing() {
179 let mut table: OidTable<i32> = OidTable::new();
180
181 table.insert(oid!(1, 3, 6, 1, 1), 50);
182 table.insert(oid!(1, 3, 6, 1, 1), 100);
183
184 assert_eq!(table.get(&oid!(1, 3, 6, 1, 1)), Some(&100));
185 assert_eq!(table.len(), 1);
186 }
187
188 #[test]
189 fn test_oid_table_get_next() {
190 let mut table: OidTable<i32> = OidTable::new();
191
192 table.insert(oid!(1, 3, 6, 1, 1), 50);
193 table.insert(oid!(1, 3, 6, 1, 2), 100);
194 table.insert(oid!(1, 3, 6, 1, 3), 150);
195
196 let next = table.get_next(&oid!(1, 3, 6, 1, 0));
198 assert!(next.is_some());
199 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 1));
200
201 let next = table.get_next(&oid!(1, 3, 6, 1, 1));
203 assert!(next.is_some());
204 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 2));
205
206 let next = table.get_next(&oid!(1, 3, 6, 1, 1, 5));
208 assert!(next.is_some());
209 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 2));
210
211 let next = table.get_next(&oid!(1, 3, 6, 1, 3));
213 assert!(next.is_none());
214
215 let next = table.get_next(&oid!(1, 3, 6, 1, 4));
216 assert!(next.is_none());
217 }
218
219 #[test]
220 fn test_oid_table_remove() {
221 let mut table: OidTable<i32> = OidTable::new();
222
223 table.insert(oid!(1, 3, 6, 1, 1), 50);
224 table.insert(oid!(1, 3, 6, 1, 2), 100);
225
226 assert_eq!(table.remove(&oid!(1, 3, 6, 1, 1)), Some(50));
227 assert_eq!(table.remove(&oid!(1, 3, 6, 1, 1)), None);
228 assert_eq!(table.len(), 1);
229 }
230
231 #[test]
232 fn test_oid_table_iter() {
233 let mut table: OidTable<i32> = OidTable::new();
234
235 table.insert(oid!(1, 3, 6, 1, 3), 150);
236 table.insert(oid!(1, 3, 6, 1, 1), 50);
237 table.insert(oid!(1, 3, 6, 1, 2), 100);
238
239 let entries: Vec<_> = table.iter().collect();
240 assert_eq!(entries.len(), 3);
241 assert_eq!(entries[0].0, &oid!(1, 3, 6, 1, 1));
242 assert_eq!(entries[1].0, &oid!(1, 3, 6, 1, 2));
243 assert_eq!(entries[2].0, &oid!(1, 3, 6, 1, 3));
244 }
245
246 #[test]
247 fn test_oid_table_empty() {
248 let table: OidTable<i32> = OidTable::new();
249 assert!(table.is_empty());
250 assert_eq!(table.len(), 0);
251 assert!(table.get_next(&oid!(1, 3, 6, 1)).is_none());
252 }
253}