1
Fork 0

Rollup merge of #87636 - Kixiron:unzip-option, r=scottmcm

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
This commit is contained in:
Yuki Okushi 2021-08-11 04:18:34 +09:00 committed by GitHub
commit bdc92f10e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 1 deletions

View file

@ -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> { impl<T: Copy> Option<&T> {
/// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the /// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
/// option. /// option.

View file

@ -68,6 +68,7 @@
#![feature(slice_group_by)] #![feature(slice_group_by)]
#![feature(trusted_random_access)] #![feature(trusted_random_access)]
#![feature(unsize)] #![feature(unsize)]
#![feature(unzip_option)]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
extern crate test; extern crate test;

View file

@ -399,7 +399,7 @@ fn test_unwrap_drop() {
} }
#[test] #[test]
pub fn option_ext() { fn option_ext() {
let thing = "{{ f }}"; let thing = "{{ f }}";
let f = thing.find("{{"); let f = thing.find("{{");
@ -407,3 +407,35 @@ pub fn option_ext() {
println!("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));
}