//! Join hashmaps with a callback for merging or failing on conflicting keys. use std::hash::Hash; use hashbrown::HashMap; use never::Never; /// Combine two hashmaps via an infallible value merger. See also /// [try_join_maps] pub fn join_maps( left: HashMap, right: HashMap, mut merge: impl FnMut(&K, V, V) -> V, ) -> HashMap { try_join_maps(left, right, |k, l, r| Ok(merge(k, l, r))).unwrap_or_else(|e: Never| match e {}) } /// Combine two hashmaps via a fallible value merger. See also [join_maps] pub fn try_join_maps( left: HashMap, mut right: HashMap, mut merge: impl FnMut(&K, V, V) -> Result, ) -> Result, E> { let mut mixed = HashMap::with_capacity(left.len() + right.len()); for (key, lval) in left { let val = match right.remove(&key) { None => lval, Some(rval) => merge(&key, lval, rval)?, }; mixed.insert(key, val); } mixed.extend(right); Ok(mixed) }