|
584 | 584 | use crate::clone::TrivialClone; |
585 | 585 | use crate::iter::{self, FusedIterator, TrustedLen}; |
586 | 586 | use crate::marker::Destruct; |
587 | | -use crate::ops::{self, ControlFlow, Deref, DerefMut}; |
| 587 | +use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try}; |
588 | 588 | use crate::panicking::{panic, panic_display}; |
589 | 589 | use crate::pin::Pin; |
590 | 590 | use crate::{cmp, convert, hint, mem, slice}; |
@@ -1816,6 +1816,49 @@ impl<T> Option<T> { |
1816 | 1816 | unsafe { self.as_mut().unwrap_unchecked() } |
1817 | 1817 | } |
1818 | 1818 |
|
| 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 | + |
1819 | 1862 | ///////////////////////////////////////////////////////////////////////// |
1820 | 1863 | // Misc |
1821 | 1864 | ///////////////////////////////////////////////////////////////////////// |
|
0 commit comments