Skip to content

Commit 1b295f4

Browse files
committed
Add or_try_* variants for HashMap Entry API
1 parent 351686b commit 1b295f4

File tree

1 file changed

+71
-5
lines changed
  • library/std/src/collections/hash

1 file changed

+71
-5
lines changed

library/std/src/collections/hash/map.rs

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,9 +2817,42 @@ impl<'a, K, V> Entry<'a, K, V> {
28172817
#[inline]
28182818
#[stable(feature = "rust1", since = "1.0.0")]
28192819
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
2820+
self.or_try_insert_with(|| Result::<_, !>::Ok(default())).unwrap()
2821+
}
2822+
2823+
/// Ensures a value is in the entry by inserting the result of a fallible default function
2824+
/// if empty, and returns a mutable reference to the value in the entry.
2825+
///
2826+
/// This methods works identically to [`or_insert_with`] except that the default function
2827+
/// should return a `Result` and, in the case of an error, the error is propagated.
2828+
///
2829+
/// [`or_insert_with`]: Self::or_insert_with
2830+
///
2831+
/// # Examples
2832+
///
2833+
/// ```
2834+
/// # #![feature(try_entry)]
2835+
/// # fn main() -> Result<(), std::num::ParseIntError> {
2836+
/// use std::collections::HashMap;
2837+
///
2838+
/// let mut map: HashMap<&str, usize> = HashMap::new();
2839+
/// let value = "42";
2840+
///
2841+
/// map.entry("poneyland").or_try_insert_with(|| value.parse())?;
2842+
///
2843+
/// assert_eq!(map["poneyland"], 42);
2844+
/// # Ok(())
2845+
/// # }
2846+
/// ```
2847+
#[inline]
2848+
#[unstable(feature = "try_entry", issue = "none")]
2849+
pub fn or_try_insert_with<F: FnOnce() -> Result<V, E>, E>(
2850+
self,
2851+
default: F,
2852+
) -> Result<&'a mut V, E> {
28202853
match self {
2821-
Occupied(entry) => entry.into_mut(),
2822-
Vacant(entry) => entry.insert(default()),
2854+
Occupied(entry) => Ok(entry.into_mut()),
2855+
Vacant(entry) => Ok(entry.insert(default()?)),
28232856
}
28242857
}
28252858

@@ -2844,11 +2877,44 @@ impl<'a, K, V> Entry<'a, K, V> {
28442877
#[inline]
28452878
#[stable(feature = "or_insert_with_key", since = "1.50.0")]
28462879
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
2880+
self.or_try_insert_with_key(|k| Result::<_, !>::Ok(default(k))).unwrap()
2881+
}
2882+
2883+
/// Ensures a value is in the entry by inserting, if empty, the result of the default function.
2884+
/// This method allows for generating key-derived values for insertion by providing the default
2885+
/// function a reference to the key that was moved during the `entry(key)` method call.
2886+
///
2887+
/// This methods works identically to [`or_insert_with_key`] except that the default function
2888+
/// should return a `Result` and, in the case of an error, the error is propagated.
2889+
///
2890+
/// [`or_insert_with_key`]: Self::or_insert_with_key
2891+
///
2892+
/// # Examples
2893+
///
2894+
/// ```
2895+
/// # #![feature(try_entry)]
2896+
/// # fn main() -> Result<(), std::num::ParseIntError> {
2897+
/// use std::collections::HashMap;
2898+
///
2899+
/// let mut map: HashMap<&str, usize> = HashMap::new();
2900+
///
2901+
/// map.entry("42").or_try_insert_with_key(|key| key.parse())?;
2902+
///
2903+
/// assert_eq!(map["42"], 42);
2904+
/// # Ok(())
2905+
/// # }
2906+
/// ```
2907+
#[inline]
2908+
#[unstable(feature = "try_entry", issue = "none")]
2909+
pub fn or_try_insert_with_key<F: FnOnce(&K) -> Result<V, E>, E>(
2910+
self,
2911+
default: F,
2912+
) -> Result<&'a mut V, E> {
28472913
match self {
2848-
Occupied(entry) => entry.into_mut(),
2914+
Occupied(entry) => Ok(entry.into_mut()),
28492915
Vacant(entry) => {
2850-
let value = default(entry.key());
2851-
entry.insert(value)
2916+
let value = default(entry.key())?;
2917+
Ok(entry.insert(value))
28522918
}
28532919
}
28542920
}

0 commit comments

Comments
 (0)