use std::borrow::Borrow; use std::collections::{hash_map, HashMap}; use std::fmt::{self, Debug}; use std::hash::{BuildHasher, Hash}; use std::iter::FromIterator; use std::ops::{Deref, DerefMut, Index}; use std::panic::UnwindSafe; #[cfg(feature = "serde")] use serde::{ de::{Deserialize, Deserializer}, ser::{Serialize, Serializer}, }; use crate::RandomState; /// A [`HashMap`](std::collections::HashMap) using [`RandomState`](crate::RandomState) to hash the items. /// (Requires the `std` feature to be enabled.) #[derive(Clone)] pub struct AHashMap(HashMap); impl From> for AHashMap { fn from(item: HashMap) -> Self { AHashMap(item) } } impl Into> for AHashMap { fn into(self) -> HashMap { self.0 } } impl AHashMap { pub fn new() -> Self { AHashMap(HashMap::with_hasher(RandomState::default())) } pub fn with_capacity(capacity: usize) -> Self { AHashMap(HashMap::with_capacity_and_hasher(capacity, RandomState::default())) } } impl AHashMap where S: BuildHasher, { pub fn with_hasher(hash_builder: S) -> Self { AHashMap(HashMap::with_hasher(hash_builder)) } pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { AHashMap(HashMap::with_capacity_and_hasher(capacity, hash_builder)) } } impl AHashMap where K: Hash + Eq, S: BuildHasher, { /// Returns a reference to the value corresponding to the key. /// /// The key may be any borrowed form of the map's key type, but /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for /// the key type. /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.get(&1), Some(&"a")); /// assert_eq!(map.get(&2), None); /// ``` #[inline] pub fn get(&self, k: &Q) -> Option<&V> where K: Borrow, Q: Hash + Eq, { self.0.get(k) } /// Returns the key-value pair corresponding to the supplied key. /// /// The supplied key may be any borrowed form of the map's key type, but /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for /// the key type. /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); /// assert_eq!(map.get_key_value(&2), None); /// ``` #[inline] pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> where K: Borrow, Q: Hash + Eq, { self.0.get_key_value(k) } /// Returns a mutable reference to the value corresponding to the key. /// /// The key may be any borrowed form of the map's key type, but /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for /// the key type. /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); /// map.insert(1, "a"); /// if let Some(x) = map.get_mut(&1) { /// *x = "b"; /// } /// assert_eq!(map[&1], "b"); /// ``` #[inline] pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> where K: Borrow, Q: Hash + Eq, { self.0.get_mut(k) } /// Inserts a key-value pair into the map. /// /// If the map did not have this key present, [`None`] is returned. /// /// If the map did have this key present, the value is updated, and the old /// value is returned. The key is not updated, though; this matters for /// types that can be `==` without being identical. See the [module-level /// documentation] for more. /// /// [module-level documentation]: crate::collections#insert-and-complex-keys /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); /// assert_eq!(map.insert(37, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[&37], "c"); /// ``` #[inline] pub fn insert(&mut self, k: K, v: V) -> Option { self.0.insert(k, v) } /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// /// The key may be any borrowed form of the map's key type, but /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for /// the key type. /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); /// map.insert(1, "a"); /// assert_eq!(map.remove(&1), Some("a")); /// assert_eq!(map.remove(&1), None); /// ``` #[inline] pub fn remove(&mut self, k: &Q) -> Option where K: Borrow, Q: Hash + Eq, { self.0.remove(k) } } impl Deref for AHashMap { type Target = HashMap; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for AHashMap { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl UnwindSafe for AHashMap where K: UnwindSafe, V: UnwindSafe, { } impl PartialEq for AHashMap where K: Eq + Hash, V: PartialEq, S: BuildHasher, { fn eq(&self, other: &AHashMap) -> bool { self.0.eq(&other.0) } } impl Eq for AHashMap where K: Eq + Hash, V: Eq, S: BuildHasher, { } impl Index<&Q> for AHashMap where K: Eq + Hash + Borrow, Q: Eq + Hash, S: BuildHasher, { type Output = V; /// Returns a reference to the value corresponding to the supplied key. /// /// # Panics /// /// Panics if the key is not present in the `HashMap`. #[inline] fn index(&self, key: &Q) -> &V { self.0.index(key) } } impl Debug for AHashMap where K: Debug, V: Debug, S: BuildHasher, { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(fmt) } } impl FromIterator<(K, V)> for AHashMap where K: Eq + Hash, S: BuildHasher + Default, { fn from_iter>(iter: T) -> Self { AHashMap(HashMap::from_iter(iter)) } } impl<'a, K, V, S> IntoIterator for &'a AHashMap { type Item = (&'a K, &'a V); type IntoIter = hash_map::Iter<'a, K, V>; fn into_iter(self) -> Self::IntoIter { (&self.0).iter() } } impl<'a, K, V, S> IntoIterator for &'a mut AHashMap { type Item = (&'a K, &'a mut V); type IntoIter = hash_map::IterMut<'a, K, V>; fn into_iter(self) -> Self::IntoIter { (&mut self.0).iter_mut() } } impl IntoIterator for AHashMap { type Item = (K, V); type IntoIter = hash_map::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } impl Extend<(K, V)> for AHashMap where K: Eq + Hash, S: BuildHasher, { #[inline] fn extend>(&mut self, iter: T) { self.0.extend(iter) } } impl<'a, K, V, S> Extend<(&'a K, &'a V)> for AHashMap where K: Eq + Hash + Copy + 'a, V: Copy + 'a, S: BuildHasher, { #[inline] fn extend>(&mut self, iter: T) { self.0.extend(iter) } } impl Default for AHashMap { #[inline] fn default() -> AHashMap { AHashMap::new() } } #[cfg(feature = "serde")] impl Serialize for AHashMap where K: Serialize + Eq + Hash, V: Serialize, { fn serialize(&self, serializer: S) -> Result { self.deref().serialize(serializer) } } #[cfg(feature = "serde")] impl<'de, K, V> Deserialize<'de> for AHashMap where K: Deserialize<'de> + Eq + Hash, V: Deserialize<'de>, { fn deserialize>(deserializer: D) -> Result { let hash_map = HashMap::deserialize(deserializer); hash_map.map(|hash_map| Self(hash_map)) } } #[cfg(test)] mod test { use super::*; #[test] fn test_borrow() { let mut map: AHashMap = AHashMap::new(); map.insert("foo".to_string(), "Bar".to_string()); map.insert("Bar".to_string(), map.get("foo").unwrap().to_owned()); } #[cfg(feature = "serde")] #[test] fn test_serde() { let mut map = AHashMap::new(); map.insert("for".to_string(), 0); map.insert("bar".to_string(), 1); let serialization = serde_json::to_string(&map).unwrap(); let deserialization: AHashMap = serde_json::from_str(&serialization).unwrap(); assert_eq!(deserialization, map); } }