1use crate::oid::Oid;
4
5#[derive(Debug, Clone)]
50pub struct OidTable<V> {
51 entries: Vec<(Oid, V)>,
53}
54
55impl<V> OidTable<V> {
56 pub fn new() -> Self {
58 Self {
59 entries: Vec::new(),
60 }
61 }
62
63 pub fn with_capacity(capacity: usize) -> Self {
65 Self {
66 entries: Vec::with_capacity(capacity),
67 }
68 }
69
70 pub fn insert(&mut self, oid: Oid, value: V) {
74 match self.entries.binary_search_by(|(o, _)| o.cmp(&oid)) {
75 Ok(idx) => self.entries[idx].1 = value,
76 Err(idx) => self.entries.insert(idx, (oid, value)),
77 }
78 }
79
80 pub fn remove(&mut self, oid: &Oid) -> Option<V> {
84 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
85 Ok(idx) => Some(self.entries.remove(idx).1),
86 Err(_) => None,
87 }
88 }
89
90 pub fn get(&self, oid: &Oid) -> Option<&V> {
92 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
93 Ok(idx) => Some(&self.entries[idx].1),
94 Err(_) => None,
95 }
96 }
97
98 pub fn get_next(&self, oid: &Oid) -> Option<(&Oid, &V)> {
102 match self.entries.binary_search_by(|(o, _)| o.cmp(oid)) {
103 Ok(idx) => {
104 self.entries.get(idx + 1).map(|(o, v)| (o, v))
106 }
107 Err(idx) => {
108 self.entries.get(idx).map(|(o, v)| (o, v))
110 }
111 }
112 }
113
114 pub fn len(&self) -> usize {
116 self.entries.len()
117 }
118
119 pub fn is_empty(&self) -> bool {
121 self.entries.is_empty()
122 }
123
124 pub fn clear(&mut self) {
126 self.entries.clear();
127 }
128
129 pub fn iter(&self) -> impl Iterator<Item = (&Oid, &V)> {
131 self.entries.iter().map(|(o, v)| (o, v))
132 }
133}
134
135impl<V> Default for OidTable<V> {
136 fn default() -> Self {
137 Self::new()
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144 use crate::oid;
145
146 #[test]
147 fn test_oid_table_insert_and_get() {
148 let mut table: OidTable<i32> = OidTable::new();
149
150 table.insert(oid!(1, 3, 6, 1, 2), 100);
151 table.insert(oid!(1, 3, 6, 1, 1), 50);
152 table.insert(oid!(1, 3, 6, 1, 3), 150);
153
154 assert_eq!(table.get(&oid!(1, 3, 6, 1, 1)), Some(&50));
156 assert_eq!(table.get(&oid!(1, 3, 6, 1, 2)), Some(&100));
157 assert_eq!(table.get(&oid!(1, 3, 6, 1, 3)), Some(&150));
158 assert_eq!(table.get(&oid!(1, 3, 6, 1, 4)), None);
159 }
160
161 #[test]
162 fn test_oid_table_update_existing() {
163 let mut table: OidTable<i32> = OidTable::new();
164
165 table.insert(oid!(1, 3, 6, 1, 1), 50);
166 table.insert(oid!(1, 3, 6, 1, 1), 100);
167
168 assert_eq!(table.get(&oid!(1, 3, 6, 1, 1)), Some(&100));
169 assert_eq!(table.len(), 1);
170 }
171
172 #[test]
173 fn test_oid_table_get_next() {
174 let mut table: OidTable<i32> = OidTable::new();
175
176 table.insert(oid!(1, 3, 6, 1, 1), 50);
177 table.insert(oid!(1, 3, 6, 1, 2), 100);
178 table.insert(oid!(1, 3, 6, 1, 3), 150);
179
180 let next = table.get_next(&oid!(1, 3, 6, 1, 0));
182 assert!(next.is_some());
183 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 1));
184
185 let next = table.get_next(&oid!(1, 3, 6, 1, 1));
187 assert!(next.is_some());
188 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 2));
189
190 let next = table.get_next(&oid!(1, 3, 6, 1, 1, 5));
192 assert!(next.is_some());
193 assert_eq!(next.unwrap().0, &oid!(1, 3, 6, 1, 2));
194
195 let next = table.get_next(&oid!(1, 3, 6, 1, 3));
197 assert!(next.is_none());
198
199 let next = table.get_next(&oid!(1, 3, 6, 1, 4));
200 assert!(next.is_none());
201 }
202
203 #[test]
204 fn test_oid_table_remove() {
205 let mut table: OidTable<i32> = OidTable::new();
206
207 table.insert(oid!(1, 3, 6, 1, 1), 50);
208 table.insert(oid!(1, 3, 6, 1, 2), 100);
209
210 assert_eq!(table.remove(&oid!(1, 3, 6, 1, 1)), Some(50));
211 assert_eq!(table.remove(&oid!(1, 3, 6, 1, 1)), None);
212 assert_eq!(table.len(), 1);
213 }
214
215 #[test]
216 fn test_oid_table_iter() {
217 let mut table: OidTable<i32> = OidTable::new();
218
219 table.insert(oid!(1, 3, 6, 1, 3), 150);
220 table.insert(oid!(1, 3, 6, 1, 1), 50);
221 table.insert(oid!(1, 3, 6, 1, 2), 100);
222
223 let entries: Vec<_> = table.iter().collect();
224 assert_eq!(entries.len(), 3);
225 assert_eq!(entries[0].0, &oid!(1, 3, 6, 1, 1));
226 assert_eq!(entries[1].0, &oid!(1, 3, 6, 1, 2));
227 assert_eq!(entries[2].0, &oid!(1, 3, 6, 1, 3));
228 }
229
230 #[test]
231 fn test_oid_table_empty() {
232 let table: OidTable<i32> = OidTable::new();
233 assert!(table.is_empty());
234 assert_eq!(table.len(), 0);
235 assert!(table.get_next(&oid!(1, 3, 6, 1)).is_none());
236 }
237}