diff --git a/src/lib.rs b/src/lib.rs index 097b6bd..8076981 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,8 @@ //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type. -#![feature(core, std_misc, hash)] +#![feature(core, std_misc)] #![cfg_attr(test, feature(test))] -#![warn(unused_qualifications, non_upper_case_globals, - variant_size_differences, unused_typecasts, - missing_docs, unused_results)] +#![warn(missing_docs, unused_results)] #[cfg(test)] extern crate test; @@ -235,11 +233,21 @@ pub enum Entry<'a, V: 'a> { } impl<'a, V: Any + Clone> Entry<'a, V> { - /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant - pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, V>> { + /// Ensures a value is in the entry by inserting the default if empty, and returns + /// a mutable reference to the value in the entry. + pub fn or_insert(self, default: V) -> &'a mut V { match self { - Entry::Occupied(inner) => Ok(inner.into_mut()), - Entry::Vacant(inner) => Err(inner), + Entry::Occupied(inner) => inner.into_mut(), + Entry::Vacant(inner) => inner.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// and returns a mutable reference to the value in the entry. + pub fn or_insert_with V>(self, default: F) -> &'a mut V { + match self { + Entry::Occupied(inner) => inner.into_mut(), + Entry::Vacant(inner) => inner.insert(default()), } } } diff --git a/src/raw.rs b/src/raw.rs index db96a0c..0ce7266 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -224,17 +224,17 @@ impl RawAnyMap { } -impl Index for RawAnyMap where TypeId: Borrow, Q: Eq + Hash { +impl Index for RawAnyMap where TypeId: Borrow, Q: Eq + Hash { type Output = Any; - fn index<'a>(&'a self, index: &Q) -> &'a Any { - self.get(index).expect("no entry found for key") + fn index<'a>(&'a self, index: Q) -> &'a Any { + self.get(&index).expect("no entry found for key") } } -impl IndexMut for RawAnyMap where TypeId: Borrow, Q: Eq + Hash { - fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut Any { - self.get_mut(index).expect("no entry found for key") +impl IndexMut for RawAnyMap where TypeId: Borrow, Q: Eq + Hash { + fn index_mut<'a>(&'a mut self, index: Q) -> &'a mut Any { + self.get_mut(&index).expect("no entry found for key") } } @@ -266,11 +266,27 @@ pub enum Entry<'a> { } impl<'a> Entry<'a> { - /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant. - pub fn get(self) -> Result<&'a mut Any, VacantEntry<'a>> { + /// Ensures a value is in the entry by inserting the default if empty, and returns + /// a mutable reference to the value in the entry. + /// + /// It is the caller’s responsibility to ensure that the key of the entry corresponds with + /// the type ID of `value`. If they do not, memory safety may be violated. + pub unsafe fn or_insert(self, default: Box) -> &'a mut Any { match self { - Entry::Occupied(inner) => Ok(inner.into_mut()), - Entry::Vacant(inner) => Err(inner), + Entry::Occupied(inner) => inner.into_mut(), + Entry::Vacant(inner) => inner.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// and returns a mutable reference to the value in the entry. + /// + /// It is the caller’s responsibility to ensure that the key of the entry corresponds with + /// the type ID of `value`. If they do not, memory safety may be violated. + pub unsafe fn or_insert_with Box>(self, default: F) -> &'a mut Any { + match self { + Entry::Occupied(inner) => inner.into_mut(), + Entry::Vacant(inner) => inner.insert(default()), } } }