Skip to content

Commit d42817d

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

File tree

1 file changed

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

1 file changed

+71
-7
lines changed

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

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,18 +2659,49 @@ 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 it will fail if the
2669+
/// call to the default function fails.
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

26682701
/// Ensures a value is in the entry by inserting, if empty, the result of the default function.
26692702
/// This method allows for generating key-derived values for insertion by providing the default
26702703
/// function a reference to the key that was moved during the `.entry(key)` method call.
26712704
///
2672-
/// The reference to the moved key is provided so that cloning or copying the key is
2673-
/// unnecessary, unlike with `.or_insert_with(|| ... )`.
26742705
///
26752706
/// # Examples
26762707
///
@@ -2686,11 +2717,44 @@ impl<'a, K, V> Entry<'a, K, V> {
26862717
#[inline]
26872718
#[stable(feature = "or_insert_with_key", since = "1.50.0")]
26882719
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
2720+
self.or_try_insert_with_key(|k| Result::<_, !>::Ok(default(k))).unwrap()
2721+
}
2722+
2723+
/// Ensures a value is in the entry by inserting, if empty, the result of the default function.
2724+
/// This method allows for generating key-derived values for insertion by providing the default
2725+
/// function a reference to the key that was moved during the `entry(key)` method call.
2726+
///
2727+
/// This methods works identically to [`or_insert_with_key`] except that it will fail if the
2728+
/// call to the default function fails.
2729+
///
2730+
/// [`or_insert_with_key`]: Self::or_insert_with_key
2731+
///
2732+
/// # Examples
2733+
///
2734+
/// ```
2735+
/// # #![feature(try_entry)]
2736+
/// # fn main() -> Result<(), std::num::ParseIntError> {
2737+
/// use std::collections::HashMap;
2738+
///
2739+
/// let mut map: HashMap<&str, usize> = HashMap::new();
2740+
///
2741+
/// map.entry("42").or_try_insert_with_key(|key| key.parse())?;
2742+
///
2743+
/// assert_eq!(map["42"], 42);
2744+
/// # Ok(())
2745+
/// # }
2746+
/// ```
2747+
#[inline]
2748+
#[unstable(feature = "try_entry", issue = "none")]
2749+
pub fn or_try_insert_with_key<F: FnOnce(&K) -> Result<V, E>, E>(
2750+
self,
2751+
default: F,
2752+
) -> Result<&'a mut V, E> {
26892753
match self {
2690-
Occupied(entry) => entry.into_mut(),
2754+
Occupied(entry) => Ok(entry.into_mut()),
26912755
Vacant(entry) => {
2692-
let value = default(entry.key());
2693-
entry.insert(value)
2756+
let value = default(entry.key())?;
2757+
Ok(entry.insert(value))
26942758
}
26952759
}
26962760
}

0 commit comments

Comments
 (0)