Path: blob/main/crates/environ/src/collections/hash_map.rs
3069 views
use crate::error::OutOfMemory;1use core::{2borrow::Borrow,3fmt,4hash::{BuildHasher, Hash},5mem,6};78#[cfg(feature = "std")]9use std::{collections::hash_map as inner, hash::RandomState as DefaultHashBuilder};1011#[cfg(not(feature = "std"))]12use hashbrown::{DefaultHashBuilder, hash_map as inner};13use wasmtime_core::alloc::TryClone;1415/// A wrapper type around [`hashbrown::hash_map::HashMap`] that only exposes16/// fallible allocation.17pub struct HashMap<K, V, S = DefaultHashBuilder> {18inner: inner::HashMap<K, V, S>,19}2021impl<K, V, S> TryClone for HashMap<K, V, S>22where23K: Eq + Hash + TryClone,24V: TryClone,25S: BuildHasher + TryClone,26{27fn try_clone(&self) -> Result<Self, OutOfMemory> {28let mut map = Self::with_capacity_and_hasher(self.len(), self.hasher().try_clone()?)?;29for (k, v) in self {30map.insert(k.try_clone()?, v.try_clone()?)31.expect("reserved capacity");32}33Ok(map)34}35}3637impl<K, V, S> Default for HashMap<K, V, S>38where39S: Default,40{41fn default() -> Self {42Self {43inner: inner::HashMap::default(),44}45}46}4748impl<K, V, S> PartialEq for HashMap<K, V, S>49where50K: Eq + Hash,51V: PartialEq,52S: BuildHasher,53{54fn eq(&self, other: &Self) -> bool {55self.inner.eq(&other.inner)56}57}5859impl<K, V, S> Eq for HashMap<K, V, S>60where61K: Eq + Hash,62V: Eq,63S: BuildHasher,64{65}6667impl<K, V, S> fmt::Debug for HashMap<K, V, S>68where69K: fmt::Debug,70V: fmt::Debug,71{72fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {73fmt::Debug::fmt(&self.inner, f)74}75}7677impl<K, V> HashMap<K, V, DefaultHashBuilder> {78/// Same as [`hashbrown::hash_map::HashMap::new`].79pub fn new() -> Self {80Self {81inner: inner::HashMap::new(),82}83}84}8586impl<K, V> HashMap<K, V, DefaultHashBuilder>87where88K: Eq + Hash,89{90/// Same as [`hashbrown::hash_map::HashMap::with_capacity`] but returns an91/// error on allocation failure.92pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {93let mut map = Self::new();94map.reserve(capacity)?;95Ok(map)96}97}9899impl<K, V, S> HashMap<K, V, S> {100/// Same as [`hashbrown::hash_map::HashMap::with_hasher`].101pub const fn with_hasher(hasher: S) -> Self {102Self {103inner: inner::HashMap::with_hasher(hasher),104}105}106107/// Same as [`hashbrown::hash_map::HashMap::hasher`].108pub fn hasher(&self) -> &S {109self.inner.hasher()110}111112/// Same as [`hashbrown::hash_map::HashMap::capacity`].113pub fn capacity(&self) -> usize {114self.inner.capacity()115}116117/// Same as [`hashbrown::hash_map::HashMap::len`].118pub fn len(&self) -> usize {119self.inner.len()120}121122/// Same as [`hashbrown::hash_map::HashMap::is_empty`].123pub fn is_empty(&self) -> bool {124self.inner.is_empty()125}126127/// Same as [`hashbrown::hash_map::HashMap::drain`].128pub fn drain(&mut self) -> inner::Drain<'_, K, V> {129self.inner.drain()130}131132/// Same as [`hashbrown::hash_map::HashMap::retain`].133pub fn retain<F>(&mut self, f: F)134where135F: FnMut(&K, &mut V) -> bool,136{137self.inner.retain(f);138}139140/// Same as [`hashbrown::hash_map::HashMap::extract_if`].141pub fn extract_if<F>(&mut self, f: F) -> inner::ExtractIf<'_, K, V, F>142where143F: FnMut(&K, &mut V) -> bool,144{145self.inner.extract_if(f)146}147148/// Same as [`hashbrown::hash_map::HashMap::clear`].149pub fn clear(&mut self) {150self.inner.clear();151}152153/// Same as [`hashbrown::hash_map::HashMap::iter`].154pub fn iter(&self) -> inner::Iter<'_, K, V> {155self.inner.iter()156}157158/// Same as [`hashbrown::hash_map::HashMap::iter_mut`].159pub fn iter_mut(&mut self) -> inner::IterMut<'_, K, V> {160self.inner.iter_mut()161}162}163164impl<K, V, S> HashMap<K, V, S>165where166K: Eq + Hash,167S: BuildHasher,168{169/// Same as [`hashbrown::hash_map::HashMap::with_capacity_and_hasher`] but170/// returns an error on allocation failure.171pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Result<Self, OutOfMemory> {172let mut map = Self::with_hasher(hasher);173map.reserve(capacity)?;174Ok(map)175}176177/// Same as [`hashbrown::hash_map::HashMap::reserve`] but returns an error178/// on allocation failure.179pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {180self.inner.try_reserve(additional).map_err(|_| {181let new_len = self.len().saturating_add(additional);182OutOfMemory::new(183new_len184.saturating_mul(mem::size_of::<K>())185.saturating_add(new_len.saturating_mul(mem::size_of::<V>())),186)187})188}189190/// Same as [`hashbrown::hash_map::HashMap::contains_key`].191pub fn contains_key<Q>(&self, key: &Q) -> bool192where193Q: Hash + Eq + ?Sized,194K: Borrow<Q>,195{196self.inner.contains_key(key)197}198199/// Same as [`hashbrown::hash_map::HashMap::get`].200pub fn get<Q>(&self, value: &Q) -> Option<&V>201where202Q: Hash + Eq + ?Sized,203K: Borrow<Q>,204{205self.inner.get(value)206}207208/// Same as [`hashbrown::hash_map::HashMap::insert`] but returns an error on209/// allocation failure.210pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, OutOfMemory> {211self.reserve(1)?;212Ok(self.inner.insert(key, value))213}214215/// Same as [`hashbrown::hash_map::HashMap::remove`].216pub fn remove<Q>(&mut self, key: &Q) -> Option<V>217where218Q: Hash + Eq + ?Sized,219K: Borrow<Q>,220{221self.inner.remove(key)222}223}224225impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {226type Item = (&'a K, &'a V);227228type IntoIter = inner::Iter<'a, K, V>;229230fn into_iter(self) -> Self::IntoIter {231self.iter()232}233}234235impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> {236type Item = (&'a K, &'a mut V);237238type IntoIter = inner::IterMut<'a, K, V>;239240fn into_iter(self) -> Self::IntoIter {241self.iter_mut()242}243}244245impl<K, V, S> IntoIterator for HashMap<K, V, S> {246type Item = (K, V);247248type IntoIter = inner::IntoIter<K, V>;249250fn into_iter(self) -> Self::IntoIter {251self.inner.into_iter()252}253}254255256