Skip to content

Commit e142458

Browse files
authored
Rollup merge of #143650 - lolbinarycat:core-option_get_or_try_insert_with-143648, r=jhpratt
core: add Option::get_or_try_insert_with Implementation for #143648
2 parents 44e34e1 + b8955c5 commit e142458

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

library/core/src/option.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@
584584
use crate::clone::TrivialClone;
585585
use crate::iter::{self, FusedIterator, TrustedLen};
586586
use crate::marker::Destruct;
587-
use crate::ops::{self, ControlFlow, Deref, DerefMut};
587+
use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try};
588588
use crate::panicking::{panic, panic_display};
589589
use crate::pin::Pin;
590590
use crate::{cmp, convert, hint, mem, slice};
@@ -1816,6 +1816,49 @@ impl<T> Option<T> {
18161816
unsafe { self.as_mut().unwrap_unchecked() }
18171817
}
18181818

1819+
/// If the option is `None`, calls the closure and inserts its output if successful.
1820+
///
1821+
/// If the closure returns a residual value such as `Err` or `None`,
1822+
/// that residual value is returned and nothing is inserted.
1823+
///
1824+
/// If the option is `Some`, nothing is inserted.
1825+
///
1826+
/// Unless a residual is returned, a mutable reference to the value
1827+
/// of the option will be output.
1828+
///
1829+
/// # Examples
1830+
///
1831+
/// ```
1832+
/// #![feature(option_get_or_try_insert_with)]
1833+
/// let mut o1: Option<u32> = None;
1834+
/// let mut o2: Option<u8> = None;
1835+
///
1836+
/// let number = "12345";
1837+
///
1838+
/// assert_eq!(o1.get_or_try_insert_with(|| number.parse()).copied(), Ok(12345));
1839+
/// assert!(o2.get_or_try_insert_with(|| number.parse()).is_err());
1840+
/// assert_eq!(o1, Some(12345));
1841+
/// assert_eq!(o2, None);
1842+
/// ```
1843+
#[inline]
1844+
#[unstable(feature = "option_get_or_try_insert_with", issue = "143648")]
1845+
pub fn get_or_try_insert_with<'a, R, F>(
1846+
&'a mut self,
1847+
f: F,
1848+
) -> <R::Residual as Residual<&'a mut T>>::TryType
1849+
where
1850+
F: FnOnce() -> R,
1851+
R: Try<Output = T, Residual: Residual<&'a mut T>>,
1852+
{
1853+
if let None = self {
1854+
*self = Some(f()?);
1855+
}
1856+
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
1857+
// variant in the code above.
1858+
1859+
Try::from_output(unsafe { self.as_mut().unwrap_unchecked() })
1860+
}
1861+
18191862
/////////////////////////////////////////////////////////////////////////
18201863
// Misc
18211864
/////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)