about summary refs log tree commit diff
path: root/src/libcore/option.rs
diff options
context:
space:
mode:
authorSebastian Hahn <sebastian@torproject.org>2017-01-25 07:13:26 +0100
committerSebastian Hahn <sebastian@torproject.org>2017-02-05 00:48:44 +0100
commit8e02ad0adab29c018148eaa399ccdfba9c098bb5 (patch)
tree374ea74cddf7ef6838b48a27be6e6c7689dd234d /src/libcore/option.rs
parent83c2d95238e3545e7ae9af4873c48b1e3651c164 (diff)
downloadrust-8e02ad0adab29c018148eaa399ccdfba9c098bb5.tar.gz
rust-8e02ad0adab29c018148eaa399ccdfba9c098bb5.zip
Provide Entry-like API for Option
This implements #39288.

Thanks to @steveklabnik and @oli-obk for their review comments :)
Diffstat (limited to 'src/libcore/option.rs')
-rw-r--r--src/libcore/option.rs70
1 files changed, 70 insertions, 0 deletions
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
@@ -633,6 +633,76 @@ impl<T> Option<T> {
     }
 
     /////////////////////////////////////////////////////////////////////////
+    // 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<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
+        match *self {
+            None => *self = Some(f()),
+            _ => (),
+        }
+
+        match *self {
+            Some(ref mut v) => v,
+            _ => unreachable!(),
+        }
+    }
+
+    /////////////////////////////////////////////////////////////////////////
     // Misc
     /////////////////////////////////////////////////////////////////////////