Skip to content

Commit 77d115c

Browse files
committed
Add or_try_* variants for HashMap Entry API
1 parent 94df917 commit 77d115c

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
@@ -2659,9 +2659,42 @@ impl<'a, K, V> Entry<'a, K, V> {
26592659
#[inline]
26602660
#[stable(feature = "rust1", since = "1.0.0")]
26612661
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
2662+
self.or_try_insert_with(|| Result::<_, !>::Ok(default())).unwrap()
2663+
}
2664+
2665+
/// Ensures a value is in the entry by inserting the result of a fallible default function
2666+
/// if empty, and returns a mutable reference to the value in the entry.
2667+
///
2668+
/// This methods works identically to [`or_insert_with`] except that the default function
2669+
/// should return a `Result` and, in the case of an error, the error is propagated.
2670+
///
2671+
/// [`or_insert_with`]: Self::or_insert_with
2672+
///
2673+
/// # Examples
2674+
///
2675+
/// ```
2676+
/// # #![feature(try_entry)]
2677+
/// # fn main() -> Result<(), std::num::ParseIntError> {
2678+
/// use std::collections::HashMap;
2679+
///
2680+
/// let mut map: HashMap<&str, usize> = HashMap::new();
2681+
/// let value = "42";
2682+
///
2683+
/// map.entry("poneyland").or_try_insert_with(|| value.parse())?;
2684+
///
2685+
/// assert_eq!(map["poneyland"], 42);
2686+
/// # Ok(())
2687+
/// # }
2688+
/// ```
2689+
#[inline]
2690+
#[unstable(feature = "try_entry", issue = "none")]
2691+
pub fn or_try_insert_with<F: FnOnce() -> Result<V, E>, E>(
2692+
self,
2693+
default: F,
2694+
) -> Result<&'a mut V, E> {
26622695
match self {
2663-
Occupied(entry) => entry.into_mut(),
2664-
Vacant(entry) => entry.insert(default()),
2696+
Occupied(entry) => Ok(entry.into_mut()),
2697+
Vacant(entry) => Ok(entry.insert(default()?)),
26652698
}
26662699
}
26672700

@@ -2686,11 +2719,44 @@ impl<'a, K, V> Entry<'a, K, V> {
26862719
#[inline]
26872720
#[stable(feature = "or_insert_with_key", since = "1.50.0")]
26882721
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
2722+
self.or_try_insert_with_key(|k| Result::<_, !>::Ok(default(k))).unwrap()
2723+
}
2724+
2725+
/// Ensures a value is in the entry by inserting, if empty, the result of the default function.
2726+
/// This method allows for generating key-derived values for insertion by providing the default
2727+
/// function a reference to the key that was moved during the `entry(key)` method call.
2728+
///
2729+
/// This methods works identically to [`or_insert_with_key`] except that the default function
2730+
/// should return a `Result` and, in the case of an error, the error is propagated.
2731+
///
2732+
/// [`or_insert_with_key`]: Self::or_insert_with_key
2733+
///
2734+
/// # Examples
2735+
///
2736+
/// ```
2737+
/// # #![feature(try_entry)]
2738+
/// # fn main() -> Result<(), std::num::ParseIntError> {
2739+
/// use std::collections::HashMap;
2740+
///
2741+
/// let mut map: HashMap<&str, usize> = HashMap::new();
2742+
///
2743+
/// map.entry("42").or_try_insert_with_key(|key| key.parse())?;
2744+
///
2745+
/// assert_eq!(map["42"], 42);
2746+
/// # Ok(())
2747+
/// # }
2748+
/// ```
2749+
#[inline]
2750+
#[unstable(feature = "try_entry", issue = "none")]
2751+
pub fn or_try_insert_with_key<F: FnOnce(&K) -> Result<V, E>, E>(
2752+
self,
2753+
default: F,
2754+
) -> Result<&'a mut V, E> {
26892755
match self {
2690-
Occupied(entry) => entry.into_mut(),
2756+
Occupied(entry) => Ok(entry.into_mut()),
26912757
Vacant(entry) => {
2692-
let value = default(entry.key());
2693-
entry.insert(value)
2758+
let value = default(entry.key())?;
2759+
Ok(entry.insert(value))
26942760
}
26952761
}
26962762
}

0 commit comments

Comments
 (0)