dfir_rs/util/
multiset.rs

1//! A multiset backed by a HashMap
2use std::collections::HashMap;
3use std::hash::Hash;
4
5/// A multiset backed by a HashMap
6#[derive(Clone, Eq, PartialEq, Debug)]
7pub struct HashMultiSet<T: Hash + Eq> {
8    items: HashMap<T, usize>,
9    len: usize,
10}
11
12impl<T: Hash + Eq> HashMultiSet<T> {
13    /// Insert item into the multiset. see `https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.insert`
14    pub fn insert(&mut self, value: T) {
15        *self.items.entry(value).or_default() += 1;
16        self.len += 1;
17    }
18}
19
20impl<T> Default for HashMultiSet<T>
21where
22    T: Hash + Eq,
23{
24    fn default() -> Self {
25        Self {
26            items: HashMap::default(),
27            len: 0,
28        }
29    }
30}
31
32impl<T> FromIterator<T> for HashMultiSet<T>
33where
34    T: Hash + Eq,
35{
36    fn from_iter<I>(iter: I) -> Self
37    where
38        I: IntoIterator<Item = T>,
39    {
40        let mut ret = HashMultiSet::default();
41
42        for item in iter {
43            ret.insert(item);
44        }
45
46        ret
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use super::*;
53
54    #[test]
55    fn basic() {
56        let mut x = HashMultiSet::default();
57
58        x.insert(1);
59        x.insert(2);
60        x.insert(2);
61
62        assert_eq!(x, HashMultiSet::from_iter([2, 1, 2]));
63    }
64}