1use std::collections::{hash_map::Entry, HashMap};
2use std::hash::Hash;
3
4pub trait NestedHashMapExtensions<K, K2, V> {
5 fn insert_into_nested(&mut self, outer_key: K, inner_key: K2, inner_value: V);
9}
10
11impl<K, K2, V> NestedHashMapExtensions<K, K2, V> for HashMap<K, HashMap<K2, V>>
12where
13 K: Hash + PartialEq + Eq,
14 K2: Hash + PartialEq + Eq,
15{
16 fn insert_into_nested(&mut self, outer_key: K, inner_key: K2, inner_value: V) {
17 match self.entry(outer_key) {
18 Entry::Occupied(mut entry) => {
19 entry.get_mut().insert(inner_key, inner_value);
20 }
21 Entry::Vacant(entry) => {
22 let mut inner = HashMap::with_capacity(1);
23 let _ = &inner.insert(inner_key, inner_value);
25 entry.insert(inner);
26 }
27 }
28 }
29}
30
31pub trait GroupExtension<K, V, I>
32where
33 K: std::hash::Hash + Ord,
34 I: IntoIterator<Item = (K, V)>,
35{
36 fn group_from(v: I) -> HashMap<K, Vec<V>>;
37}
38
39impl<K, V, I> GroupExtension<K, V, I> for HashMap<K, Vec<V>>
40where
41 K: std::hash::Hash + Ord,
42 I: IntoIterator<Item = (K, V)>,
43{
44 fn group_from(v: I) -> HashMap<K, Vec<V>> {
45 let mut result = HashMap::<K, Vec<V>>::new();
46 for (a, b) in v {
47 result.entry(a).or_default().push(b);
48 }
49 result
50 }
51}