|
578 | 578 |
|
579 | 579 | use crate::iter::{self, FusedIterator, TrustedLen};
|
580 | 580 | use crate::marker::Destruct;
|
581 |
| -use crate::ops::{self, ControlFlow, Deref, DerefMut}; |
| 581 | +use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try}; |
582 | 582 | use crate::panicking::{panic, panic_display};
|
583 | 583 | use crate::pin::Pin;
|
584 | 584 | use crate::{cmp, convert, hint, mem, slice};
|
@@ -1807,6 +1807,49 @@ impl<T> Option<T> {
|
1807 | 1807 | unsafe { self.as_mut().unwrap_unchecked() }
|
1808 | 1808 | }
|
1809 | 1809 |
|
| 1810 | + /// If the option is `None`, calls the closure and inserts its output if successful. |
| 1811 | + /// |
| 1812 | + /// If the closure returns a residual value such as `Err` or `None`, |
| 1813 | + /// that residual value is returned and nothing is inserted. |
| 1814 | + /// |
| 1815 | + /// If the option is `Some`, nothing is inserted. |
| 1816 | + /// |
| 1817 | + /// Unless a residual is returned, a mutable reference to the value |
| 1818 | + /// of the option will be output. |
| 1819 | + /// |
| 1820 | + /// # Examples |
| 1821 | + /// |
| 1822 | + /// ``` |
| 1823 | + /// #![feature(option_get_or_try_insert_with)] |
| 1824 | + /// let mut o1: Option<u32> = None; |
| 1825 | + /// let mut o2: Option<u8> = None; |
| 1826 | + /// |
| 1827 | + /// let number = "12345"; |
| 1828 | + /// |
| 1829 | + /// assert_eq!(o1.get_or_try_insert_with(|| number.parse()).copied(), Ok(12345)); |
| 1830 | + /// assert!(o2.get_or_try_insert_with(|| number.parse()).is_err()); |
| 1831 | + /// assert_eq!(o1, Some(12345)); |
| 1832 | + /// assert_eq!(o2, None); |
| 1833 | + /// ``` |
| 1834 | + #[inline] |
| 1835 | + #[unstable(feature = "option_get_or_try_insert_with", issue = "143648")] |
| 1836 | + pub fn get_or_try_insert_with<'a, R, F>( |
| 1837 | + &'a mut self, |
| 1838 | + f: F, |
| 1839 | + ) -> <R::Residual as Residual<&'a mut T>>::TryType |
| 1840 | + where |
| 1841 | + F: FnOnce() -> R, |
| 1842 | + R: Try<Output = T, Residual: Residual<&'a mut T>>, |
| 1843 | + { |
| 1844 | + if let None = self { |
| 1845 | + *self = Some(f()?); |
| 1846 | + } |
| 1847 | + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` |
| 1848 | + // variant in the code above. |
| 1849 | + |
| 1850 | + Try::from_output(unsafe { self.as_mut().unwrap_unchecked() }) |
| 1851 | + } |
| 1852 | + |
1810 | 1853 | /////////////////////////////////////////////////////////////////////////
|
1811 | 1854 | // Misc
|
1812 | 1855 | /////////////////////////////////////////////////////////////////////////
|
|
0 commit comments