|
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