oxihuman_core/
sequence_map.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct SeqEntry<V> {
11 pub key: String,
12 pub value: V,
13 pub seq: u64,
14}
15
16#[allow(dead_code)]
18pub struct SequenceMap<V> {
19 entries: Vec<SeqEntry<V>>,
20 next_seq: u64,
21}
22
23#[allow(dead_code)]
24impl<V: Clone> SequenceMap<V> {
25 pub fn new() -> Self {
26 Self {
27 entries: Vec::new(),
28 next_seq: 0,
29 }
30 }
31
32 pub fn insert(&mut self, key: &str, value: V) -> u64 {
33 let seq = self.next_seq;
34 self.next_seq += 1;
35 if let Some(e) = self.entries.iter_mut().find(|e| e.key == key) {
36 e.value = value;
37 e.seq = seq;
38 } else {
39 self.entries.push(SeqEntry {
40 key: key.to_string(),
41 value,
42 seq,
43 });
44 }
45 seq
46 }
47
48 pub fn remove(&mut self, key: &str) -> bool {
49 let before = self.entries.len();
50 self.entries.retain(|e| e.key != key);
51 self.entries.len() < before
52 }
53
54 pub fn get(&self, key: &str) -> Option<&V> {
55 self.entries.iter().find(|e| e.key == key).map(|e| &e.value)
56 }
57
58 pub fn get_by_index(&self, index: usize) -> Option<&SeqEntry<V>> {
59 self.entries.get(index)
60 }
61
62 pub fn index_of(&self, key: &str) -> Option<usize> {
63 self.entries.iter().position(|e| e.key == key)
64 }
65
66 pub fn contains(&self, key: &str) -> bool {
67 self.entries.iter().any(|e| e.key == key)
68 }
69
70 pub fn len(&self) -> usize {
71 self.entries.len()
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.entries.is_empty()
76 }
77
78 pub fn keys(&self) -> Vec<&str> {
79 self.entries.iter().map(|e| e.key.as_str()).collect()
80 }
81
82 pub fn values(&self) -> Vec<&V> {
83 self.entries.iter().map(|e| &e.value).collect()
84 }
85
86 pub fn clear(&mut self) {
87 self.entries.clear();
88 }
89
90 pub fn next_seq(&self) -> u64 {
91 self.next_seq
92 }
93
94 pub fn seq_of(&self, key: &str) -> Option<u64> {
95 self.entries.iter().find(|e| e.key == key).map(|e| e.seq)
96 }
97}
98
99impl<V: Clone> Default for SequenceMap<V> {
100 fn default() -> Self {
101 Self::new()
102 }
103}
104
105pub fn new_sequence_map<V: Clone>() -> SequenceMap<V> {
106 SequenceMap::new()
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn insert_and_get() {
115 let mut m: SequenceMap<i32> = new_sequence_map();
116 m.insert("a", 1);
117 assert_eq!(m.get("a"), Some(&1));
118 }
119
120 #[test]
121 fn preserves_order() {
122 let mut m: SequenceMap<i32> = new_sequence_map();
123 m.insert("first", 1);
124 m.insert("second", 2);
125 assert_eq!(m.keys(), vec!["first", "second"]);
126 }
127
128 #[test]
129 fn update_in_place() {
130 let mut m: SequenceMap<i32> = new_sequence_map();
131 m.insert("k", 1);
132 m.insert("k", 99);
133 assert_eq!(m.get("k"), Some(&99));
134 assert_eq!(m.len(), 1);
135 }
136
137 #[test]
138 fn remove_entry() {
139 let mut m: SequenceMap<i32> = new_sequence_map();
140 m.insert("x", 5);
141 assert!(m.remove("x"));
142 assert!(!m.contains("x"));
143 }
144
145 #[test]
146 fn index_of() {
147 let mut m: SequenceMap<i32> = new_sequence_map();
148 m.insert("a", 1);
149 m.insert("b", 2);
150 assert_eq!(m.index_of("b"), Some(1));
151 }
152
153 #[test]
154 fn get_by_index() {
155 let mut m: SequenceMap<i32> = new_sequence_map();
156 m.insert("z", 7);
157 let e = m.get_by_index(0).expect("should succeed");
158 assert_eq!(e.key, "z");
159 }
160
161 #[test]
162 fn seq_increments() {
163 let mut m: SequenceMap<i32> = new_sequence_map();
164 let s1 = m.insert("a", 1);
165 let s2 = m.insert("b", 2);
166 assert!(s2 > s1);
167 }
168
169 #[test]
170 fn is_empty() {
171 let m: SequenceMap<i32> = new_sequence_map();
172 assert!(m.is_empty());
173 }
174
175 #[test]
176 fn clear() {
177 let mut m: SequenceMap<i32> = new_sequence_map();
178 m.insert("a", 1);
179 m.clear();
180 assert!(m.is_empty());
181 }
182
183 #[test]
184 fn seq_of_known_key() {
185 let mut m: SequenceMap<i32> = new_sequence_map();
186 let seq = m.insert("key", 1);
187 assert_eq!(m.seq_of("key"), Some(seq));
188 }
189}