1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
use std::{borrow::Borrow, collections::HashSet, hash::Hash, mem::replace}; pub struct ChainSet<T> { pub(crate) sets: Vec<HashSet<T>>, } impl<T: Hash + Eq> ChainSet<T> { pub fn new(set: HashSet<T>) -> Self { Self { sets: vec![set] } } pub fn insert(&mut self, value: T) -> bool { if let Some(set) = self.sets.last_mut() { set.insert(value) } else { let mut set = HashSet::new(); set.insert(value); self.sets.push(set); false } } pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> where T: Borrow<Q>, Q: Hash + Eq, { for set in self.sets.iter().rev() { if let Some(v) = set.get(value) { return Some(v); } } None } pub fn new_child(&mut self) { self.sets.push(HashSet::new()); } pub fn new_child_with(&mut self, map: HashSet<T>) { self.sets.push(map); } pub fn remove_child(&mut self) -> Option<HashSet<T>> { if self.sets.len() == 1 { let ret = replace(&mut self.sets[0], HashSet::new()); Some(ret) } else { self.sets.pop() } } } impl<T: Hash + Eq> Default for ChainSet<T> { fn default() -> Self { Self { sets: vec![HashSet::new()], } } } #[cfg(test)] mod test { use super::*; use std::default::Default; #[test] fn initialization() { let mut test_set = HashSet::new(); test_set.insert("test"); let chain_set = ChainSet::new(test_set); assert!(chain_set.sets.len() > 0); assert_eq!(chain_set.sets[0].get("test"), Some(&"test")); } #[test] fn initialization_default() { let chain_set: ChainSet<()> = ChainSet::default(); assert!(chain_set.sets.len() > 0); assert!(chain_set.sets[0].is_empty()); } #[test] fn insert() { let mut chain_set = ChainSet::default(); assert!(chain_set.insert("test")); assert_eq!(chain_set.sets[0].get("test"), Some(&"test")); } #[test] fn get() { let mut chain_set = ChainSet::default(); chain_set.insert("test"); assert_eq!(chain_set.get(&"test"), Some(&"test")); } #[test] fn get_none() { let chain_set: ChainSet<&str> = ChainSet::default(); assert_eq!(chain_set.get(&"test"), None); } #[test] fn new_child() { let mut chain_set = ChainSet::default(); chain_set.insert("test"); chain_set.new_child(); assert!(chain_set.sets.len() > 1); } #[test] #[ignore] fn scopes() { let mut chain_set = ChainSet::default(); chain_set.insert("x"); chain_set.insert("y"); chain_set.new_child(); assert!(chain_set.insert("x")); } #[test] fn remove_child() { let mut chain_set = ChainSet::default(); chain_set.insert("x"); chain_set.insert("y"); chain_set.new_child(); chain_set.insert("x"); let ret = chain_set.remove_child().unwrap(); assert_eq!(ret.get("x"), Some(&"x")); assert_eq!(chain_set.get("x"), Some(&"x")); } #[test] fn remove_child_length_1() { let mut chain_set = ChainSet::default(); chain_set.insert("x"); let _ = chain_set.remove_child(); assert_eq!(chain_set.get("x"), None); assert!(chain_set.sets.len() == 1); } }