From a71686f4ea1a265f15adfbe850305f65453ef550 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 17 Dec 2014 12:10:13 -0800 Subject: [PATCH] std: Second pass stabilization of Result This commit, like the second pass of `Option`, largely just stablizes the existing functionality after renaming a few iterators. The specific actions taken were: * The `Ok` and `Err` variants were marked `#[stable]` as the stability inheritance was since removed. * The `as_mut` method is now stable. * The `map` method is now stable * The `map_err` method is now stable * The `iter`, `iter_mut`, and `into_iter` methods now returned structures named after the method of iteration. The methods are also now all stable. * The `and_then` method is now stable. * The `or_else` method is now stable. * The `unwrap` family of functions are now all stable: `unwrap_or`, `unwrap_or_else`, `unwrap`, and `unwrap_err`. There is a possible open extension to `Result::{and, and_then}` to make the return type further generic over `FromError` (as proposed in #19078), but this is a backwards compatible change due to the usage of default type parameters, which makes the two functions safe to stabilize now regardless of the outcome of that issue. --- src/libcore/result.rs | 148 ++++++++++++++++++++++++++---------------- 1 file changed, 92 insertions(+), 56 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 00a2a3d5854..b59734a7d98 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -230,15 +230,15 @@ #![stable] -use self::Result::*; +use self::Result::{Ok, Err}; -use std::fmt::Show; -use slice; -use slice::AsSlice; +use clone::Clone; +use fmt::Show; use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; -use option::Option; -use option::Option::{None, Some}; use ops::{FnMut, FnOnce}; +use option::Option::{mod, None, Some}; +use slice::AsSlice; +use slice; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). /// @@ -248,9 +248,11 @@ use ops::{FnMut, FnOnce}; #[stable] pub enum Result { /// Contains the success value + #[stable] Ok(T), /// Contains the error value + #[stable] Err(E) } @@ -258,6 +260,7 @@ pub enum Result { // Type implementation ///////////////////////////////////////////////////////////////////////////// +#[stable] impl Result { ///////////////////////////////////////////////////////////////////////// // Querying the contained values @@ -300,7 +303,6 @@ impl Result { !self.is_ok() } - ///////////////////////////////////////////////////////////////////////// // Adapter for each variant ///////////////////////////////////////////////////////////////////////// @@ -369,7 +371,7 @@ impl Result { /// ``` #[inline] #[stable] - pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> { + pub fn as_ref(&self) -> Result<&T, &E> { match *self { Ok(ref x) => Ok(x), Err(ref x) => Err(x), @@ -395,8 +397,8 @@ impl Result { /// assert_eq!(x.unwrap_err(), 0); /// ``` #[inline] - #[unstable = "waiting for mut conventions"] - pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> { + #[stable] + pub fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { Ok(ref mut x) => Ok(x), Err(ref mut x) => Err(x), @@ -420,7 +422,7 @@ impl Result { /// ``` #[inline] #[unstable = "waiting for mut conventions"] - pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] { + pub fn as_mut_slice(&mut self) -> &mut [T] { match *self { Ok(ref mut x) => slice::mut_ref_slice(x), Err(_) => { @@ -465,11 +467,11 @@ impl Result { /// assert!(sum == 10); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn map U>(self, op: F) -> Result { match self { - Ok(t) => Ok(op(t)), - Err(e) => Err(e) + Ok(t) => Ok(op(t)), + Err(e) => Err(e) } } @@ -491,15 +493,14 @@ impl Result { /// assert_eq!(x.map_err(stringify), Err("error code: 13".to_string())); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn map_err F>(self, op: O) -> Result { match self { - Ok(t) => Ok(t), - Err(e) => Err(op(e)) + Ok(t) => Ok(t), + Err(e) => Err(op(e)) } } - ///////////////////////////////////////////////////////////////////////// // Iterator constructors ///////////////////////////////////////////////////////////////////////// @@ -516,9 +517,9 @@ impl Result { /// assert_eq!(x.iter().next(), None); /// ``` #[inline] - #[unstable = "waiting for iterator conventions"] - pub fn iter<'r>(&'r self) -> Item<&'r T> { - Item{opt: self.as_ref().ok()} + #[stable] + pub fn iter(&self) -> Iter { + Iter { inner: self.as_ref().ok() } } /// Returns a mutable iterator over the possibly contained value. @@ -537,9 +538,9 @@ impl Result { /// assert_eq!(x.iter_mut().next(), None); /// ``` #[inline] - #[unstable = "waiting for iterator conventions"] - pub fn iter_mut<'r>(&'r mut self) -> Item<&'r mut T> { - Item{opt: self.as_mut().ok()} + #[stable] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { inner: self.as_mut().ok() } } /// Returns a consuming iterator over the possibly contained value. @@ -556,9 +557,9 @@ impl Result { /// assert_eq!(v, vec![]); /// ``` #[inline] - #[unstable = "waiting for iterator conventions"] - pub fn into_iter(self) -> Item { - Item{opt: self.ok()} + #[stable] + pub fn into_iter(self) -> IntoIter { + IntoIter { inner: self.ok() } } //////////////////////////////////////////////////////////////////////// @@ -611,7 +612,7 @@ impl Result { /// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3)); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn and_then Result>(self, op: F) -> Result { match self { Ok(t) => op(t), @@ -665,7 +666,7 @@ impl Result { /// assert_eq!(Err(3).or_else(err).or_else(err), Err(3)); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn or_else Result>(self, op: O) -> Result { match self { Ok(t) => Ok(t), @@ -687,7 +688,7 @@ impl Result { /// assert_eq!(x.unwrap_or(optb), optb); /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap_or(self, optb: T) -> T { match self { Ok(t) => t, @@ -707,7 +708,7 @@ impl Result { /// assert_eq!(Err("foo").unwrap_or_else(count), 3u); /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap_or_else T>(self, op: F) -> T { match self { Ok(t) => t, @@ -716,6 +717,7 @@ impl Result { } } +#[stable] impl Result { /// Unwraps a result, yielding the content of an `Ok`. /// @@ -736,7 +738,7 @@ impl Result { /// x.unwrap(); // panics with `emergency failure` /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap(self) -> T { match self { Ok(t) => t, @@ -746,6 +748,7 @@ impl Result { } } +#[stable] impl Result { /// Unwraps a result, yielding the content of an `Err`. /// @@ -766,7 +769,7 @@ impl Result { /// assert_eq!(x.unwrap_err(), "emergency failure"); /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap_err(self) -> E { match self { Ok(t) => @@ -797,42 +800,75 @@ impl AsSlice for Result { } ///////////////////////////////////////////////////////////////////////////// -// The Result Iterator +// The Result Iterators ///////////////////////////////////////////////////////////////////////////// -/// A `Result` iterator that yields either one or zero elements -/// -/// The `Item` iterator is returned by the `iter`, `iter_mut` and `into_iter` -/// methods on `Result`. -#[deriving(Clone)] -#[unstable = "waiting for iterator conventions"] -pub struct Item { - opt: Option -} +/// An iterator over a reference to the `Ok` variant of a `Result`. +#[stable] +pub struct Iter<'a, T: 'a> { inner: Option<&'a T> } -impl Iterator for Item { +impl<'a, T> Iterator<&'a T> for Iter<'a, T> { #[inline] - fn next(&mut self) -> Option { - self.opt.take() - } - + fn next(&mut self) -> Option<&'a T> { self.inner.take() } #[inline] fn size_hint(&self) -> (uint, Option) { - match self.opt { - Some(_) => (1, Some(1)), - None => (0, Some(0)), - } + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) } } -impl DoubleEndedIterator for Item { +impl<'a, T> DoubleEndedIterator<&'a T> for Iter<'a, T> { #[inline] - fn next_back(&mut self) -> Option { - self.opt.take() + fn next_back(&mut self) -> Option<&'a T> { self.inner.take() } +} + +impl<'a, T> ExactSizeIterator<&'a T> for Iter<'a, T> {} + +impl<'a, T> Clone for Iter<'a, T> { + fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } } +} + +/// An iterator over a mutable reference to the `Ok` variant of a `Result`. +#[stable] +pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> } + +impl<'a, T> Iterator<&'a mut T> for IterMut<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a mut T> { self.inner.take() } + #[inline] + fn size_hint(&self) -> (uint, Option) { + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) } } -impl ExactSizeIterator for Item {} +impl<'a, T> DoubleEndedIterator<&'a mut T> for IterMut<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() } +} + +impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {} + +/// An iterator over the value in a `Ok` variant of a `Result`. +#[stable] +pub struct IntoIter { inner: Option } + +impl Iterator for IntoIter { + #[inline] + fn next(&mut self) -> Option { self.inner.take() } + #[inline] + fn size_hint(&self) -> (uint, Option) { + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { self.inner.take() } +} + +impl ExactSizeIterator for IntoIter {} ///////////////////////////////////////////////////////////////////////////// // FromIterator