From 8e02ad0adab29c018148eaa399ccdfba9c098bb5 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Wed, 25 Jan 2017 07:13:26 +0100 Subject: [PATCH] Provide Entry-like API for Option This implements #39288. Thanks to @steveklabnik and @oli-obk for their review comments :) --- src/libcore/option.rs | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 8871e1fa840..f4f582495af 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -632,6 +632,76 @@ impl Option { } } + ///////////////////////////////////////////////////////////////////////// + // Entry-like operations to insert if None and return a reference + ///////////////////////////////////////////////////////////////////////// + + /// Inserts `v` into the option if it is `None`, then + /// returns a mutable reference to the contained value. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_entry)] + /// + /// let mut x = None; + /// + /// { + /// let y: &mut u32 = x.get_or_insert(5); + /// assert_eq!(y, &5); + /// + /// *y = 7; + /// } + /// + /// assert_eq!(x, Some(7)); + /// ``` + #[inline] + #[unstable(feature = "option_entry", issue = "39288")] + pub fn get_or_insert(&mut self, v: T) -> &mut T { + match *self { + None => *self = Some(v), + _ => (), + } + + match *self { + Some(ref mut v) => v, + _ => unreachable!(), + } + } + + /// Inserts a value computed from `f` into the option if it is `None`, then + /// returns a mutable reference to the contained value. + /// + /// # Examples + /// + /// ``` + /// #![feature(option_entry)] + /// + /// let mut x = None; + /// + /// { + /// let y: &mut u32 = x.get_or_insert_with(|| 5); + /// assert_eq!(y, &5); + /// + /// *y = 7; + /// } + /// + /// assert_eq!(x, Some(7)); + /// ``` + #[inline] + #[unstable(feature = "option_entry", issue = "39288")] + pub fn get_or_insert_with T>(&mut self, f: F) -> &mut T { + match *self { + None => *self = Some(f()), + _ => (), + } + + match *self { + Some(ref mut v) => v, + _ => unreachable!(), + } + } + ///////////////////////////////////////////////////////////////////////// // Misc /////////////////////////////////////////////////////////////////////////