use std::{ collections::{btree_map, hash_map, BTreeMap, HashMap}, hash::Hash, }; use anyhow::{bail, Result}; pub trait NestedMap { fn nested_insert(&mut self, v1: T1, v2: T2, v3: T3) -> Result<()>; } pub trait NestedVec { fn nested_push(&mut self, v1: T1, v2: T2); fn nested_remove(&mut self, v1: &T1, v2: &T2); } impl NestedMap for BTreeMap> where T1: Eq + Ord, T2: Eq + Ord, { fn nested_insert(&mut self, v1: T1, v2: T2, v3: T3) -> Result<()> { match self.entry(v1).or_default().entry(v2) { btree_map::Entry::Occupied(_) => bail!("Entry already exists"), btree_map::Entry::Vacant(entry) => entry.insert(v3), }; Ok(()) } } impl NestedMap for HashMap> where T1: Eq + Hash, T2: Eq + Hash, { fn nested_insert(&mut self, v1: T1, v2: T2, v3: T3) -> Result<()> { match self.entry(v1).or_default().entry(v2) { hash_map::Entry::Occupied(_) => bail!("Entry already exists"), hash_map::Entry::Vacant(entry) => entry.insert(v3), }; Ok(()) } } impl NestedVec for BTreeMap> where T1: Ord, T2: PartialEq, { fn nested_push(&mut self, v1: T1, v2: T2) { self.entry(v1).or_default().push(v2); } fn nested_remove(&mut self, v1: &T1, v2: &T2) { if let Some(vec) = self.get_mut(v1) { vec.retain(|n| n != v2); } } } impl NestedVec for HashMap> where T1: Ord + Hash, T2: PartialEq, { fn nested_push(&mut self, v1: T1, v2: T2) { self.entry(v1).or_default().push(v2); } fn nested_remove(&mut self, v1: &T1, v2: &T2) { if let Some(vec) = self.get_mut(v1) { vec.retain(|n| n != v2); } } }