shadow_rs/utility/
once_set.rs1use std::collections::HashSet;
2use std::sync::RwLock;
3
4#[derive(Debug, Default)]
7pub struct OnceSet<T>(RwLock<Option<HashSet<T>>>);
8
9impl<T> OnceSet<T>
10where
11 T: std::cmp::Eq + std::hash::Hash,
12{
13 pub const fn new() -> Self {
14 Self(RwLock::new(None))
15 }
16
17 pub fn insert(&self, val: T) -> bool {
20 if self
22 .0
23 .read()
24 .unwrap()
25 .as_ref()
26 .map(|x| x.contains(&val))
27 .unwrap_or(false)
28 {
29 return false;
31 }
32
33 self.0
37 .write()
38 .unwrap()
39 .get_or_insert_with(HashSet::new)
40 .insert(val)
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn test_once_set() {
50 let set = OnceSet::new();
51
52 assert!(set.insert("FOO".to_string()));
53 assert!(set.insert("BAR".to_string()));
54 assert!(!set.insert("FOO".to_string()));
55 assert!(!set.insert("BAR".to_string()));
56 assert!(!set.insert("BAR".to_string()));
57 assert!(set.insert("XYZ".to_string()));
58 assert!(!set.insert("XYZ".to_string()));
59 }
60}