Skip to content

Commit

Permalink
Rollup merge of rust-lang#87636 - Kixiron:unzip-option, r=scottmcm
Browse files Browse the repository at this point in the history
Added the `Option::unzip()` method

* Adds the `Option::unzip()` method to turn an `Option<(T, U)>` into `(Option<T>, Option<U>)` under the `unzip_option` feature
* Adds tests for both `Option::unzip()` and `Option::zip()`, I noticed that `.zip()` didn't have any
* Adds `#[inline]` to a few of `Option`'s methods that were missing it
  • Loading branch information
JohnTitor committed Aug 10, 2021
2 parents 33186e4 + ab2c590 commit 28e84e4
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
27 changes: 27 additions & 0 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,33 @@ impl<T> Option<T> {
}
}

impl<T, U> Option<(T, U)> {
/// Unzips an option containing a tuple of two options
///
/// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`.
/// Otherwise, `(None, None)` is returned.
///
/// # Examples
///
/// ```
/// #![feature(unzip_option)]
///
/// let x = Some((1, "hi"));
/// let y = None::<(u8, u32)>;
///
/// assert_eq!(x.unzip(), (Some(1), Some("hi")));
/// assert_eq!(y.unzip(), (None, None));
/// ```
#[inline]
#[unstable(feature = "unzip_option", issue = "87800", reason = "recently added")]
pub const fn unzip(self) -> (Option<T>, Option<U>) {
match self {
Some((a, b)) => (Some(a), Some(b)),
None => (None, None),
}
}
}

impl<T: Copy> Option<&T> {
/// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
/// option.
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#![feature(slice_group_by)]
#![feature(trusted_random_access)]
#![feature(unsize)]
#![feature(unzip_option)]
#![deny(unsafe_op_in_unsafe_fn)]

extern crate test;
Expand Down
34 changes: 33 additions & 1 deletion library/core/tests/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,43 @@ fn test_unwrap_drop() {
}

#[test]
pub fn option_ext() {
fn option_ext() {
let thing = "{{ f }}";
let f = thing.find("{{");

if f.is_none() {
println!("None!");
}
}

#[test]
fn zip_options() {
let x = Some(10);
let y = Some("foo");
let z: Option<usize> = None;

assert_eq!(x.zip(y), Some((10, "foo")));
assert_eq!(x.zip(z), None);
assert_eq!(z.zip(x), None);
}

#[test]
fn unzip_options() {
let x = Some((10, "foo"));
let y = None::<(bool, i32)>;

assert_eq!(x.unzip(), (Some(10), Some("foo")));
assert_eq!(y.unzip(), (None, None));
}

#[test]
fn zip_unzip_roundtrip() {
let x = Some(10);
let y = Some("foo");

let z = x.zip(y);
assert_eq!(z, Some((10, "foo")));

let a = z.unzip();
assert_eq!(a, (x, y));
}

0 comments on commit 28e84e4

Please sign in to comment.