|
576 | 576 | #![stable(feature = "rust1", since = "1.0.0")] |
577 | 577 |
|
578 | 578 | use crate::iter::{self, FusedIterator, TrustedLen}; |
579 | | -use crate::ops::{self, ControlFlow, Deref, DerefMut}; |
| 579 | +use crate::ops::{self, ControlFlow, Deref, DerefMut, Residual, Try}; |
580 | 580 | use crate::panicking::{panic, panic_display}; |
581 | 581 | use crate::pin::Pin; |
582 | 582 | use crate::{cmp, convert, hint, mem, slice}; |
@@ -1758,6 +1758,49 @@ impl<T> Option<T> { |
1758 | 1758 | unsafe { self.as_mut().unwrap_unchecked() } |
1759 | 1759 | } |
1760 | 1760 |
|
| 1761 | + /// If the option is `None`, calls the closure and inserts its output if successful. |
| 1762 | + /// |
| 1763 | + /// If the closure returns a residual value such as `Err` or `None`, |
| 1764 | + /// that residual value is returned and nothing is inserted. |
| 1765 | + /// |
| 1766 | + /// If the option is `Some`, nothing is inserted. |
| 1767 | + /// |
| 1768 | + /// Unless a residual is returned, a mutable reference to the value |
| 1769 | + /// of the option will be output. |
| 1770 | + /// |
| 1771 | + /// # Examples |
| 1772 | + /// |
| 1773 | + /// ``` |
| 1774 | + /// #![feature(option_get_or_try_insert_with)] |
| 1775 | + /// let mut o1: Option<u32> = None; |
| 1776 | + /// let mut o2: Option<u8> = None; |
| 1777 | + /// |
| 1778 | + /// let number = "12345"; |
| 1779 | + /// |
| 1780 | + /// assert_eq!(o1.get_or_try_insert_with(|| number.parse()).copied(), Ok(12345)); |
| 1781 | + /// assert!(o2.get_or_try_insert_with(|| number.parse()).is_err()); |
| 1782 | + /// assert_eq!(o1, Some(12345)); |
| 1783 | + /// assert_eq!(o2, None); |
| 1784 | + /// ``` |
| 1785 | + #[inline] |
| 1786 | + #[unstable(feature = "option_get_or_try_insert_with", issue = "143648")] |
| 1787 | + pub fn get_or_try_insert_with<'a, R, F>( |
| 1788 | + &'a mut self, |
| 1789 | + f: F, |
| 1790 | + ) -> <R::Residual as Residual<&'a mut T>>::TryType |
| 1791 | + where |
| 1792 | + F: FnOnce() -> R, |
| 1793 | + R: Try<Output = T, Residual: Residual<&'a mut T>>, |
| 1794 | + { |
| 1795 | + if let None = self { |
| 1796 | + *self = Some(f()?); |
| 1797 | + } |
| 1798 | + // SAFETY: a `None` variant for `self` would have been replaced by a `Some` |
| 1799 | + // variant in the code above. |
| 1800 | + |
| 1801 | + Try::from_output(unsafe { self.as_mut().unwrap_unchecked() }) |
| 1802 | + } |
| 1803 | + |
1761 | 1804 | ///////////////////////////////////////////////////////////////////////// |
1762 | 1805 | // Misc |
1763 | 1806 | ///////////////////////////////////////////////////////////////////////// |
|
0 commit comments