Skip to content

Commit 9b90e17

Browse files
committed
add insert and insert_with to Option
This removes a cause of `unwrap` and code complexity. This allows replacing ``` option_value = Some(build()); option_value.as_mut().unwrap() ``` with ``` option_value.insert(build()) ``` or ``` option_value.insert_with(build) ``` It's also useful in contexts not requiring the mutability of the reference. Here's a typical cache example: ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => { cache = Some(compute_cache_entry()); // unwrap is OK because we just filled the option &cache.as_ref().unwrap().content } }; ``` It can be changed into ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => &cache.insert_with(compute_cache_entry).content, }; ```
1 parent a9cd294 commit 9b90e17

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

library/core/src/option.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,52 @@ impl<T> Option<T> {
562562
}
563563
}
564564

565+
/////////////////////////////////////////////////////////////////////////
566+
// Setting a new value
567+
/////////////////////////////////////////////////////////////////////////
568+
569+
/// Inserts `v` into the option then returns a mutable reference
570+
/// to the contained value.
571+
///
572+
/// # Example
573+
///
574+
/// ```
575+
/// #![feature(option_insert)]
576+
///
577+
/// let mut o = None;
578+
/// let v = o.insert(3);
579+
/// assert_eq!(*v, 3);
580+
/// ```
581+
#[inline]
582+
#[unstable(feature = "option_insert", reason = "new API", issue = "none")]
583+
pub fn insert(&mut self, v: T) -> &mut T {
584+
self.insert_with(|| v)
585+
}
586+
587+
/// Inserts a value computed from `f` into the option, then returns a
588+
/// mutable reference to the contained value.
589+
///
590+
/// # Example
591+
///
592+
/// ```
593+
/// #![feature(option_insert)]
594+
///
595+
/// let mut o = None;
596+
/// let v = o.insert_with(|| 3);
597+
/// assert_eq!(*v, 3);
598+
/// ```
599+
#[inline]
600+
#[unstable(feature = "option_insert", reason = "new API", issue = "none")]
601+
pub fn insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
602+
*self = Some(f());
603+
604+
match *self {
605+
Some(ref mut v) => v,
606+
// SAFETY: the code above just filled the option
607+
None => unsafe { hint::unreachable_unchecked() },
608+
}
609+
}
610+
565611
/////////////////////////////////////////////////////////////////////////
566612
// Iterator constructors
567613
/////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)