1mod node;
2
3pub struct SemverStore<T> {
4 tree: node::Node<T>,
5}
6
7impl<T> SemverStore<T> {
8 pub fn new() -> Self {
9 SemverStore {
10 tree: node::Node::new(0),
11 }
12 }
13
14 pub fn insert(&mut self, version: &String, store: T) {
15 let semver: Vec<&str> = version.split('.').collect();
16 let mut current_node = &mut self.tree;
17 for v in semver {
18 let version_number = v.parse::<u32>().unwrap();
19 let node = node::Node::new(version_number);
20 current_node = current_node.add_child(node);
21 }
22 current_node.set_store(store);
23 }
24
25 pub fn get(&mut self, version: &String) -> Option<&T> {
26 let semver: Vec<&str> = version.split('.').collect();
27 let major = semver.get(0).unwrap();
28 let minor = semver.get(1).unwrap();
29 let patch = semver.get(2).unwrap_or(&"x");
30
31 if let &"x" = minor {
32 return self
33 .tree
34 .get_child(int(&major))
35 .and_then(|major| major.get_max_child())
36 .and_then(|minor| minor.get_max_child())
37 .and_then(|patch| patch.store.as_ref());
38 }
39
40 if let &"x" = patch {
41 return self
42 .tree
43 .get_child(int(&major))
44 .and_then(|major| major.get_child(int(&minor)))
45 .and_then(|minor| minor.get_max_child())
46 .and_then(|patch| patch.store.as_ref());
47 }
48
49 self.tree
50 .get_child(int(&major))
51 .and_then(|major| major.get_child(int(&minor)))
52 .and_then(|minor| minor.get_child(int(&patch)))
53 .and_then(|patch| patch.store.as_ref())
54 }
55
56 pub fn contains_key(&mut self, version: &String) -> bool {
57 match self.get(version) {
58 Some(_v) => true,
59 None => false,
60 }
61 }
62
63 pub fn remove(&mut self, version: &String) -> Option<T> {
64 if self.contains_key(&version) == false {
65 return None;
66 }
67
68 let semver: Vec<&str> = version.split('.').collect();
69 let major = semver.get(0).unwrap();
70 let minor = semver.get(1).unwrap();
71 let patch = semver.get(2).unwrap_or(&"x");
72
73 let major_node = self.tree.get_child(int(&major)).unwrap();
74
75 if let &"x" = minor {
77 let minor_prefix = major_node
78 .get_max_child()
79 .and_then(|minor| Some(minor.prefix))
80 .unwrap();
81
82 let patch_prefix = major_node
83 .get_child(minor_prefix)
84 .and_then(|minor| minor.get_max_child())
85 .and_then(|patch| Some(patch.prefix))
86 .unwrap();
87
88 let patch_node = major_node
89 .get_child(minor_prefix)
90 .and_then(|minor| minor.remove_child(patch_prefix));
91
92 self.tree.remove_child(int(&major));
93
94 return patch_node.and_then(|node| node.store);
95 }
96
97 let minor_node = major_node.get_child(int(&minor)).unwrap();
98
99 if let &"x" = patch {
101 let patch_prefix = minor_node
102 .get_max_child()
103 .and_then(|patch| Some(patch.prefix))
104 .unwrap();
105
106 let patch_node = minor_node.remove_child(patch_prefix);
107
108 major_node.remove_child(int(&minor));
109 if major_node.children.len() == 0 {
110 self.tree.remove_child(int(&major));
111 }
112
113 return patch_node.and_then(|node| node.store);
114 }
115
116 let patch_node = minor_node.remove_child(int(&patch));
118
119 if minor_node.children.len() == 0 {
122 major_node.remove_child(int(&minor));
123 }
124 if major_node.children.len() == 0 {
125 self.tree.remove_child(int(&major));
126 }
127
128 return patch_node.and_then(|node| node.store);
129 }
130
131 pub fn empty(&mut self) {
132 self.tree = node::Node::new(0);
133 }
134}
135
136fn int(str: &str) -> u32 {
137 str.parse::<u32>().unwrap()
138}
139
140#[cfg(test)]
141mod semver_store_tests {
142 use super::SemverStore;
143
144 #[test]
145 fn create_a_store() {
146 let store = SemverStore::<i32>::new();
147 assert_eq!(store.tree.prefix, 0);
148 }
149
150 #[test]
151 fn store_a_string() {
152 let mut store = SemverStore::<String>::new();
153 store.insert(&"1.0.0".to_string(), "hello".to_string());
154 assert_eq!(store.get(&"1.0.0".to_string()).unwrap(), &"hello");
155 }
156
157 #[test]
158 fn not_found() {
159 let mut store = SemverStore::<i32>::new();
160 store.insert(&"1.0.0".to_string(), 1);
161 assert_eq!(store.get(&"1.2.0".to_string()), None);
162 assert_eq!(store.get(&"1.0.1".to_string()), None);
163 assert_eq!(store.get(&"1.1.x".to_string()), None);
164 assert_eq!(store.get(&"2.0.0".to_string()), None);
165 assert_eq!(store.get(&"2.1".to_string()), None);
166 assert_eq!(store.get(&"2.x".to_string()), None);
167 }
168
169 #[test]
170 fn store_multiple_values() {
171 let mut store = SemverStore::<i32>::new();
172 store.insert(&"1.0.0".to_string(), 1);
173 store.insert(&"1.1.0".to_string(), 2);
174 store.insert(&"1.2.0".to_string(), 3);
175 store.insert(&"1.3.0".to_string(), 4);
176
177 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 4);
179 assert_eq!(store.get(&"1.0.0".to_string()).unwrap(), &1);
180 assert_eq!(store.get(&"1.1.0".to_string()).unwrap(), &2);
181 assert_eq!(store.get(&"1.2.0".to_string()).unwrap(), &3);
182 assert_eq!(store.get(&"1.3.0".to_string()).unwrap(), &4);
183 }
184
185 #[test]
186 fn store_has_key() {
187 let mut store = SemverStore::<i32>::new();
188 store.insert(&"1.0.0".to_string(), 1);
189 store.insert(&"1.1.0".to_string(), 2);
190 store.insert(&"1.2.0".to_string(), 3);
191 store.insert(&"1.3.0".to_string(), 4);
192
193 assert_eq!(store.contains_key(&"1.1.0".to_string()), true);
194 assert_eq!(store.contains_key(&"1.2.3".to_string()), false);
195 }
196
197 #[test]
198 fn store_multiple_values_and_multiple_prefixes() {
199 let mut store = SemverStore::<i32>::new();
200 store.insert(&"1.1.0".to_string(), 11);
201 store.insert(&"1.2.0".to_string(), 12);
202 store.insert(&"1.3.0".to_string(), 13);
203
204 store.insert(&"2.0.0".to_string(), 21);
205 store.insert(&"2.1.0".to_string(), 22);
206 store.insert(&"2.2.0".to_string(), 23);
207 store.insert(&"2.3.0".to_string(), 24);
208
209 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 3);
210 assert_eq!(store.tree.children.get(&2).unwrap().children.len(), 4);
211
212 assert_eq!(store.get(&"1.1.0".to_string()).unwrap(), &11);
213 assert_eq!(store.get(&"1.2.0".to_string()).unwrap(), &12);
214 assert_eq!(store.get(&"1.3.0".to_string()).unwrap(), &13);
215
216 assert_eq!(store.get(&"2.0.0".to_string()).unwrap(), &21);
217 assert_eq!(store.get(&"2.1.0".to_string()).unwrap(), &22);
218 assert_eq!(store.get(&"2.2.0".to_string()).unwrap(), &23);
219 assert_eq!(store.get(&"2.3.0".to_string()).unwrap(), &24);
220 }
221
222 #[test]
223 fn delete_stored_values() {
224 let mut store = SemverStore::<i32>::new();
225 store.insert(&"1.0.0".to_string(), 1);
226 store.insert(&"1.1.0".to_string(), 2);
227 store.insert(&"1.2.0".to_string(), 3);
228 store.insert(&"1.3.0".to_string(), 4);
229
230 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 4);
231 assert_eq!(store.remove(&"1.2.0".to_string()), Some(3));
232 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 3);
233 assert_eq!(store.remove(&"2.2.0".to_string()), None);
234 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 3);
235 assert_eq!(store.remove(&"1.4.2".to_string()), None);
236 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 3);
237 }
238
239 #[test]
240 fn delete_minor_wildcard_shortcut() {
241 let mut store = SemverStore::<i32>::new();
242 store.insert(&"1.0.0".to_string(), 1);
243 store.insert(&"1.1.0".to_string(), 2);
244 store.insert(&"1.1.1".to_string(), 3);
245 store.insert(&"1.1.2".to_string(), 4);
246 store.insert(&"1.2.0".to_string(), 5);
247 store.insert(&"1.2.1".to_string(), 6);
248 store.insert(&"1.2.2".to_string(), 7);
249
250 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 3);
251 assert_eq!(store.remove(&"1.1.x".to_string()), Some(4));
252 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 2);
253 assert_eq!(store.remove(&"1.2".to_string()), Some(7));
254 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 1);
255 assert_eq!(store.remove(&"1.3".to_string()), None);
256 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 1);
257 assert_eq!(store.remove(&"1.3.x".to_string()), None);
258 assert_eq!(store.tree.children.get(&1).unwrap().children.len(), 1);
259 }
260
261 #[test]
262 fn delete_major_wildcard_shortcut() {
263 let mut store = SemverStore::<i32>::new();
264 store.insert(&"1.0.0".to_string(), 1);
265 store.insert(&"1.1.0".to_string(), 2);
266 store.insert(&"2.0.0".to_string(), 3);
267 store.insert(&"2.1.0".to_string(), 4);
268 store.insert(&"3.0.0".to_string(), 5);
269 store.insert(&"3.1.0".to_string(), 6);
270
271 assert_eq!(store.tree.children.len(), 3);
272 assert_eq!(store.remove(&"1.x".to_string()), Some(2));
273 assert_eq!(store.tree.children.len(), 2);
274 assert_eq!(store.remove(&"2.x".to_string()), Some(4));
275 assert_eq!(store.tree.children.len(), 1);
276 assert_eq!(store.remove(&"4.x".to_string()), None);
277 assert_eq!(store.tree.children.len(), 1);
278 }
279
280 #[test]
281 fn get_patch_wildcard_shortcut() {
282 let mut store = SemverStore::<i32>::new();
283 store.insert(&"1.0.1".to_string(), 1);
284 store.insert(&"1.0.2".to_string(), 2);
285 store.insert(&"1.0.3".to_string(), 3);
286 store.insert(&"2.0.0".to_string(), 4);
287
288 assert_eq!(store.get(&"1.0.x".to_string()).unwrap(), &3);
289 assert_eq!(store.get(&"1.0".to_string()).unwrap(), &3);
290 }
291
292 #[test]
293 fn get_minor_wildcard() {
294 let mut store = SemverStore::<i32>::new();
295 store.insert(&"1.0.1".to_string(), 1);
296 store.insert(&"1.1.2".to_string(), 2);
297 store.insert(&"1.2.3".to_string(), 3);
298 store.insert(&"2.0.0".to_string(), 4);
299
300 assert_eq!(store.get(&"1.1".to_string()).unwrap(), &2);
301 assert_eq!(store.get(&"1.x".to_string()).unwrap(), &3);
302 }
303
304 #[test]
305 fn empty_store() {
306 let mut store = SemverStore::<String>::new();
307 store.insert(&"1.0.0".to_string(), "hello".to_string());
308 assert_eq!(store.get(&"1.0.0".to_string()).unwrap(), &"hello");
309 store.empty();
310 assert_eq!(store.get(&"1.0.0".to_string()), None);
311 }
312}