diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 3f12f563bc4..c3c0c5ef20f 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4560,14 +4560,14 @@ pub fn count_traits_and_supertraits(tcx: ctxt, } pub fn get_tydesc_ty(tcx: ctxt) -> Result { - do tcx.lang_items.require(TyDescStructLangItem).map_move |tydesc_lang_item| { + do tcx.lang_items.require(TyDescStructLangItem).map |tydesc_lang_item| { tcx.intrinsic_defs.find_copy(&tydesc_lang_item) .expect("Failed to resolve TyDesc") } } pub fn get_opaque_ty(tcx: ctxt) -> Result { - do tcx.lang_items.require(OpaqueStructLangItem).map_move |opaque_lang_item| { + do tcx.lang_items.require(OpaqueStructLangItem).map |opaque_lang_item| { tcx.intrinsic_defs.find_copy(&opaque_lang_item) .expect("Failed to resolve Opaque") } diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 37910cef60e..c34d20ed4f5 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -2464,7 +2464,7 @@ fn test_timer_sleep_simple() { unsafe { let io = local_io(); let timer = io.timer_init(); - do timer.map_move |mut t| { t.sleep(1) }; + do timer.map |mut t| { t.sleep(1) }; } } } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 732dbe64d01..0d9dc18726f 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -8,94 +8,86 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Operations on the ubiquitous `Option` type. - -Type `Option` represents an optional value. - -Every `Option` value can either be `Some(T)` or `None`. Where in other -languages you might use a nullable type, in Rust you would use an option -type. - -Options are most commonly used with pattern matching to query the presence -of a value and take action, always accounting for the `None` case. - -# Example - - ``` -let msg = Some(~"howdy"); - -// Take a reference to the contained string -match msg { - Some(ref m) => io::println(*m), - None => () -} - -// Remove the contained string, destroying the Option -let unwrapped_msg = match msg { - Some(m) => m, - None => ~"default message" -}; - ``` - -*/ +//! Operations on the ubiquitous `Option` type. +//! +//! Type `Option` represents an optional value. +//! +//! Every `Option` value can either be `Some(T)` or `None`. Where in other +//! languages you might use a nullable type, in Rust you would use an option +//! type. +//! +//! Options are most commonly used with pattern matching to query the presence +//! of a value and take action, always accounting for the `None` case. +//! +//! # Example +//! +//! ``` +//! let msg = Some(~"howdy"); +//! +//! // Take a reference to the contained string +//! match msg { +//! Some(ref m) => io::println(*m), +//! None => () +//! } +//! +//! // Remove the contained string, destroying the Option +//! let unwrapped_msg = match msg { +//! Some(m) => m, +//! None => ~"default message" +//! }; +//! ``` +use any::Any; use clone::Clone; -use cmp::{Eq,Ord}; -use default::Default; -use either; -use util; -use num::Zero; -use iter; -use iter::{Iterator, DoubleEndedIterator, ExactSize}; -use result; -use str::{StrSlice, OwnedStr}; -use to_str::ToStr; use clone::DeepClone; +use cmp::{Eq, TotalEq, TotalOrd}; +use default::Default; +use fmt; +use iter::{Iterator, DoubleEndedIterator, ExactSize}; +use kinds::Send; +use result::{IntoResult, ToResult, AsResult}; +use result::{Result, Ok, Err}; +use str::OwnedStr; +use to_str::ToStr; +use util; /// The option type -#[deriving(Clone, DeepClone, Eq)] -#[allow(missing_doc)] +#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)] pub enum Option { + /// No value None, - Some(T), + /// Some value `T` + Some(T) } -impl Ord for Option { - fn lt(&self, other: &Option) -> bool { - iter::order::lt(self.iter(), other.iter()) - } - - fn le(&self, other: &Option) -> bool { - iter::order::le(self.iter(), other.iter()) - } - - fn ge(&self, other: &Option) -> bool { - iter::order::ge(self.iter(), other.iter()) - } - - fn gt(&self, other: &Option) -> bool { - iter::order::gt(self.iter(), other.iter()) - } -} - -// FIXME: #8242 implementing manually because deriving doesn't work for some reason -impl ToStr for Option { - fn to_str(&self) -> ~str { - match *self { - Some(ref x) => { - let mut s = ~"Some("; - s.push_str(x.to_str()); - s.push_str(")"); - s - } - None => ~"None" - } - } -} +///////////////////////////////////////////////////////////////////////////// +// Type implementation +///////////////////////////////////////////////////////////////////////////// impl Option { + ///////////////////////////////////////////////////////////////////////// + // Querying the contained values + ///////////////////////////////////////////////////////////////////////// + + /// Returns true if the option contains a `Some` value + #[inline] + pub fn is_some(&self) -> bool { + match *self { + Some(_) => true, + None => false + } + } + + /// Returns true if the option equals `None` + #[inline] + pub fn is_none(&self) -> bool { + !self.is_some() + } + + ///////////////////////////////////////////////////////////////////////// + // Adapter for working with references + ///////////////////////////////////////////////////////////////////////// + /// Convert from `Option` to `Option<&T>` #[inline] pub fn as_ref<'r>(&'r self) -> Option<&'r T> { @@ -108,6 +100,64 @@ impl Option { match *self { Some(ref mut x) => Some(x), None => None } } + ///////////////////////////////////////////////////////////////////////// + // Getting to contained values + ///////////////////////////////////////////////////////////////////////// + + /// Unwraps a option, yielding the content of a `Some` + /// Fails if the value is a `None` with a custom failure message provided by `msg`. + #[inline] + pub fn expect(self, msg: M) -> T { + match self { + Some(val) => val, + None => fail!(msg), + } + } + + /// Moves a value out of an option type and returns it. + /// + /// Useful primarily for getting strings, vectors and unique pointers out + /// of option types without copying them. + /// + /// # Failure + /// + /// Fails if the value equals `None`. + /// + /// # Safety note + /// + /// In general, because this function may fail, its use is discouraged. + /// Instead, prefer to use pattern matching and handle the `None` + /// case explicitly. + #[inline] + pub fn unwrap(self) -> T { + match self { + Some(val) => val, + None => fail!("called `Option::unwrap()` on a `None` value"), + } + } + + /// Returns the contained value or a default + #[inline] + pub fn unwrap_or(self, def: T) -> T { + match self { + Some(x) => x, + None => def + } + } + + /// Returns the contained value or computes it from a closure + #[inline] + pub fn unwrap_or_else(self, f: &fn() -> T) -> T { + match self { + Some(x) => x, + None => f() + } + } + + ///////////////////////////////////////////////////////////////////////// + // Transforming contained values + ///////////////////////////////////////////////////////////////////////// + /// Maps an `Option` to `Option` by applying a function to a contained value. #[inline] pub fn map(self, f: &fn(T) -> U) -> Option { @@ -120,6 +170,31 @@ impl Option { match self { None => def, Some(t) => f(t) } } + /// Apply a function to the contained value or do nothing. + /// Returns true if the contained value was mutated. + pub fn mutate(&mut self, f: &fn(T) -> T) -> bool { + if self.is_some() { + *self = Some(f(self.take_unwrap())); + true + } else { false } + } + + /// Apply a function to the contained value or set it to a default. + /// Returns true if the contained value was mutated, or false if set to the default. + pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) -> bool { + if self.is_some() { + *self = Some(f(self.take_unwrap())); + true + } else { + *self = Some(def); + false + } + } + + ///////////////////////////////////////////////////////////////////////// + // Iterator constructors + ///////////////////////////////////////////////////////////////////////// + /// Return an iterator over the possibly contained value #[inline] pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> { @@ -144,19 +219,13 @@ impl Option { OptionIterator{opt: self} } - /// Returns true if the option equals `None` - #[inline] - pub fn is_none(&self) -> bool { - match *self { None => true, Some(_) => false } - } - - /// Returns true if the option contains a `Some` value - #[inline] - pub fn is_some(&self) -> bool { !self.is_none() } + ///////////////////////////////////////////////////////////////////////// + // Boolean operations on the values, eager and lazy + ///////////////////////////////////////////////////////////////////////// /// Returns `None` if the option is `None`, otherwise returns `optb`. #[inline] - pub fn and(self, optb: Option) -> Option { + pub fn and(self, optb: Option) -> Option { match self { Some(_) => optb, None => None, @@ -192,7 +261,17 @@ impl Option { } } - /// Filters an optional value using given function. + ///////////////////////////////////////////////////////////////////////// + // Misc + ///////////////////////////////////////////////////////////////////////// + + /// Take the value out of the option, leaving a `None` in its place. + #[inline] + pub fn take(&mut self) -> Option { + util::replace(self, None) + } + + /// Filters an optional value using a given function. #[inline(always)] pub fn filtered(self, f: &fn(t: &T) -> bool) -> Option { match self { @@ -201,33 +280,33 @@ impl Option { } } - /// Take the value out of the option, leaving a `None` in its place. + /// Applies a function zero or more times until the result is `None`. #[inline] - pub fn take(&mut self) -> Option { - util::replace(self, None) - } - - /// Apply a function to the contained value or do nothing. - /// Returns true if the contained value was mutated. - pub fn mutate(&mut self, f: &fn(T) -> T) -> bool { - if self.is_some() { - *self = Some(f(self.take_unwrap())); - true - } else { false } - } - - /// Apply a function to the contained value or set it to a default. - /// Returns true if the contained value was mutated, or false if set to the default. - pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) -> bool { - if self.is_some() { - *self = Some(f(self.take_unwrap())); - true - } else { - *self = Some(def); - false + pub fn while_some(self, blk: &fn(v: T) -> Option) { + let mut opt = self; + while opt.is_some() { + opt = blk(opt.unwrap()); } } + ///////////////////////////////////////////////////////////////////////// + // Common special cases + ///////////////////////////////////////////////////////////////////////// + + /// The option dance. Moves a value out of an option type and returns it, + /// replacing the original with `None`. + /// + /// # Failure + /// + /// Fails if the value equals `None`. + #[inline] + pub fn take_unwrap(&mut self) -> T { + if self.is_none() { + fail!("called `Option::take_unwrap()` on a `None` value") + } + self.take().unwrap() + } + /// Gets an immutable reference to the value inside an option. /// /// # Failure @@ -267,85 +346,23 @@ impl Option { None => fail!("called `Option::get_mut_ref()` on a `None` value"), } } +} - /// Moves a value out of an option type and returns it. - /// - /// Useful primarily for getting strings, vectors and unique pointers out - /// of option types without copying them. - /// - /// # Failure - /// - /// Fails if the value equals `None`. - /// - /// # Safety note - /// - /// In general, because this function may fail, its use is discouraged. - /// Instead, prefer to use pattern matching and handle the `None` - /// case explicitly. +impl Option { + /// Returns the contained value or default (for this type) #[inline] - pub fn unwrap(self) -> T { + pub fn unwrap_or_default(self) -> T { match self { Some(x) => x, - None => fail!("called `Option::unwrap()` on a `None` value"), - } - } - - /// The option dance. Moves a value out of an option type and returns it, - /// replacing the original with `None`. - /// - /// # Failure - /// - /// Fails if the value equals `None`. - #[inline] - pub fn take_unwrap(&mut self) -> T { - if self.is_none() { - fail!("called `Option::take_unwrap()` on a `None` value") - } - self.take().unwrap() - } - - /// Gets the value out of an option, printing a specified message on - /// failure - /// - /// # Failure - /// - /// Fails if the value equals `None` - #[inline] - pub fn expect(self, reason: &str) -> T { - match self { - Some(val) => val, - None => fail!("{}", reason.to_owned()), - } - } - - /// Returns the contained value or a default - #[inline] - pub fn unwrap_or(self, def: T) -> T { - match self { - Some(x) => x, - None => def - } - } - - /// Returns the contained value or computes it from a closure - #[inline] - pub fn unwrap_or_else(self, f: &fn() -> T) -> T { - match self { - Some(x) => x, - None => f() - } - } - - /// Applies a function zero or more times until the result is `None`. - #[inline] - pub fn while_some(self, blk: &fn(v: T) -> Option) { - let mut opt = self; - while opt.is_some() { - opt = blk(opt.unwrap()); + None => Default::default() } } } +///////////////////////////////////////////////////////////////////////////// +// Constructor extension trait +///////////////////////////////////////////////////////////////////////////// + /// A generic trait for converting a value to a `Option` pub trait ToOption { /// Convert to the `option` type @@ -384,53 +401,47 @@ impl AsOption for Option { } } -impl result::ToResult for Option { +///////////////////////////////////////////////////////////////////////////// +// Trait implementations +///////////////////////////////////////////////////////////////////////////// + +impl ToResult for Option { #[inline] - fn to_result(&self) -> result::Result { + fn to_result(&self) -> Result { match *self { - Some(ref x) => result::Ok(x.clone()), - None => result::Err(()), + Some(ref x) => Ok(x.clone()), + None => Err(()), } } } -impl result::IntoResult for Option { +impl IntoResult for Option { #[inline] - fn into_result(self) -> result::Result { + fn into_result(self) -> Result { match self { - Some(x) => result::Ok(x), - None => result::Err(()), + Some(x) => Ok(x), + None => Err(()), } } } -impl either::ToEither<(), T> for Option { +impl AsResult for Option { #[inline] - fn to_either(&self) -> either::Either<(), T> { + fn as_result<'a>(&'a self) -> Result<&'a T, &'a ()> { + static UNIT: () = (); match *self { - Some(ref x) => either::Right(x.clone()), - None => either::Left(()), + Some(ref t) => Ok(t), + None => Err(&UNIT), } } } -impl either::IntoEither<(), T> for Option { +impl fmt::Default for Option { #[inline] - fn into_either(self) -> either::Either<(), T> { - match self { - Some(x) => either::Right(x), - None => either::Left(()), - } - } -} - -impl Option { - /// Returns the contained value or default (for this type) - #[inline] - pub fn unwrap_or_default(self) -> T { - match self { - Some(x) => x, - None => Default::default() + fn fmt(s: &Option, f: &mut fmt::Formatter) { + match *s { + Some(ref t) => write!(f.buf, "Some({})", *t), + None => write!(f.buf, "None") } } } @@ -440,16 +451,9 @@ impl Default for Option { fn default() -> Option { None } } -impl Option { - /// Returns the contained value or zero (for this type) - #[inline] - pub fn unwrap_or_zero(self) -> T { - match self { - Some(x) => x, - None => Zero::zero() - } - } -} +///////////////////////////////////////////////////////////////////////////// +// The Option Iterator +///////////////////////////////////////////////////////////////////////////// /// An iterator that yields either one or zero elements #[deriving(Clone, DeepClone)] @@ -481,14 +485,17 @@ impl DoubleEndedIterator for OptionIterator { impl ExactSize for OptionIterator {} +///////////////////////////////////////////////////////////////////////////// +// Tests +///////////////////////////////////////////////////////////////////////////// + #[cfg(test)] mod tests { use super::*; - use either::{IntoEither, ToEither}; - use either; use result::{IntoResult, ToResult}; - use result; + use result::{Ok, Err}; + use str::StrSlice; use util; #[test] @@ -550,6 +557,7 @@ mod tests { assert_eq!(y2, 5); assert!(y.is_none()); } + #[test] #[should_fail] fn test_option_too_much_dance() { let mut y = Some(util::NonCopyable); @@ -561,11 +569,11 @@ mod tests { fn test_and() { let x: Option = Some(1); assert_eq!(x.and(Some(2)), Some(2)); - assert_eq!(x.and(None), None); + assert_eq!(x.and(None::), None); let x: Option = None; assert_eq!(x.and(Some(2)), None); - assert_eq!(x.and(None), None); + assert_eq!(x.and(None::), None); } #[test] @@ -630,7 +638,7 @@ mod tests { #[test] #[should_fail] - fn test_unwrap_fail() { + fn test_unwrap_fail2() { let x: Option<~str> = None; x.unwrap(); } @@ -653,14 +661,6 @@ mod tests { assert_eq!(x.unwrap_or_else(|| 2), 2); } - #[test] - fn test_unwrap_or_zero() { - let some_stuff = Some(42); - assert_eq!(some_stuff.unwrap_or_zero(), 42); - let no_stuff: Option = None; - assert_eq!(no_stuff.unwrap_or_zero(), 0); - } - #[test] fn test_filtered() { let some_stuff = Some(42); @@ -765,8 +765,8 @@ mod tests { let some: Option = Some(100); let none: Option = None; - assert_eq!(some.to_result(), result::Ok(100)); - assert_eq!(none.to_result(), result::Err(())); + assert_eq!(some.to_result(), Ok(100)); + assert_eq!(none.to_result(), Err(())); } #[test] @@ -774,25 +774,7 @@ mod tests { let some: Option = Some(100); let none: Option = None; - assert_eq!(some.into_result(), result::Ok(100)); - assert_eq!(none.into_result(), result::Err(())); - } - - #[test] - pub fn test_to_either() { - let some: Option = Some(100); - let none: Option = None; - - assert_eq!(some.to_either(), either::Right(100)); - assert_eq!(none.to_either(), either::Left(())); - } - - #[test] - pub fn test_into_either() { - let some: Option = Some(100); - let none: Option = None; - - assert_eq!(some.into_either(), either::Right(100)); - assert_eq!(none.into_either(), either::Left(())); + assert_eq!(some.into_result(), Ok(100)); + assert_eq!(none.into_result(), Err(())); } } diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 957ba4a0438..03860c8ab22 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,26 +10,25 @@ //! A type representing either success or failure -#[allow(missing_doc)]; - +use any::Any; use clone::Clone; use cmp::Eq; -use either; -use iter::Iterator; -use option::{None, Option, Some, OptionIterator}; -use option; -use vec; -use vec::OwnedVector; -use to_str::ToStr; -use str::StrSlice; use fmt; +use iter::Iterator; +use kinds::Send; +use option::{None, Option, Some, OptionIterator}; +use option::{ToOption, IntoOption, AsOption}; +use str::OwnedStr; +use to_str::ToStr; +use vec::OwnedVector; +use vec; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). /// /// In order to provide informative error messages, `E` is required to implement `ToStr`. /// It is further recommended for `E` to be a descriptive error type, eg a `enum` for /// all possible errors cases. -#[deriving(Clone, Eq)] +#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)] pub enum Result { /// Contains the successful result value Ok(T), @@ -37,20 +36,14 @@ pub enum Result { Err(E) } +///////////////////////////////////////////////////////////////////////////// +// Type implementation +///////////////////////////////////////////////////////////////////////////// + impl Result { - /// Get a reference to the value out of a successful result - /// - /// # Failure - /// - /// If the result is an error - #[inline] - pub fn get_ref<'a>(&'a self) -> &'a T { - match *self { - Ok(ref t) => t, - Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: {}", - e.to_str()), - } - } + ///////////////////////////////////////////////////////////////////////// + // Querying the contained values + ///////////////////////////////////////////////////////////////////////// /// Returns true if the result is `Ok` #[inline] @@ -67,12 +60,114 @@ impl Result { !self.is_ok() } - /// Call a method based on a previous result + ///////////////////////////////////////////////////////////////////////// + // Adapter for working with references + ///////////////////////////////////////////////////////////////////////// + + /// Convert from `Result` to `Result<&T, &E>` + #[inline] + pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> { + match *self { + Ok(ref x) => Ok(x), + Err(ref x) => Err(x), + } + } + + /// Convert from `Result` to `Result<&mut T, &mut E>` + #[inline] + pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> { + match *self { + Ok(ref mut x) => Ok(x), + Err(ref mut x) => Err(x), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Getting to contained values + ///////////////////////////////////////////////////////////////////////// + + /// Unwraps a result, yielding the content of an `Ok`. + /// Fails if the value is a `Err` with a custom failure message provided by `msg`. + #[inline] + pub fn expect(self, msg: M) -> T { + match self { + Ok(t) => t, + Err(_) => fail!(msg), + } + } + + /// Unwraps a result, yielding the content of an `Err`. + /// Fails if the value is a `Ok` with a custom failure message provided by `msg`. + #[inline] + pub fn expect_err(self, msg: M) -> E { + match self { + Err(e) => e, + Ok(_) => fail!(msg), + } + } + + /// Unwraps a result, yielding the content of an `Ok`. + /// Fails if the value is a `Err` with an error message derived + /// from `E`'s `ToStr` implementation. + #[inline] + pub fn unwrap(self) -> T { + match self { + Ok(t) => t, + Err(e) => fail!("called `Result::unwrap()` on `Err` value '{}'", + e.to_str()), + } + } + + /// Unwraps a result, yielding the content of an `Err`. + /// Fails if the value is a `Ok`. + #[inline] + pub fn unwrap_err(self) -> E { + match self { + Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"), + Err(e) => e + } + } + + ///////////////////////////////////////////////////////////////////////// + // Transforming contained values + ///////////////////////////////////////////////////////////////////////// + + /// Maps an `Result` to `Result` by applying a function to an + /// contained `Ok` value, leaving an `Err` value untouched. /// - /// If `self` is `Ok` then the value is extracted and passed to `op` - /// whereupon `op`s result is returned. if `self` is `Err` then it is - /// immediately returned. This function can be used to compose the results - /// of two functions. + /// This function can be used to compose the results of two functions. + /// + /// Example: + /// + /// let res = do read_file(file).map |buf| { + /// parse_bytes(buf) + /// } + #[inline] + pub fn map(self, op: &fn(T) -> U) -> Result { + match self { + Ok(t) => Ok(op(t)), + Err(e) => Err(e) + } + } + + /// Maps an `Result` to `Result` by applying a function to an + /// contained `Err` value, leaving an `Ok` value untouched. + /// + /// This function can be used to pass through a successful result while handling + /// an error. + #[inline] + pub fn map_err(self, op: &fn(E) -> F) -> Result { + match self { + Ok(t) => Ok(t), + Err(e) => Err(op(e)) + } + } + + ///////////////////////////////////////////////////////////////////////// + // Iterator constructors + ///////////////////////////////////////////////////////////////////////// + + /// Returns an `Iterator` over one or zero references to the value of an `Ok` /// /// Example: /// @@ -87,12 +182,7 @@ impl Result { }.move_iter() } - /// Call a method based on a previous result - /// - /// If `self` is `Err` then the value is extracted and passed to `op` - /// whereupon `op`s result is returned. if `self` is `Ok` then it is - /// immediately returned. This function can be used to pass through a - /// successful result while handling an error. + /// Returns an `Iterator` over one or zero references to the value of an `Err` #[inline] pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> { match *self { @@ -101,103 +191,22 @@ impl Result { }.move_iter() } - /// Unwraps a result, yielding the content of an `Ok`. - /// Fails if the value is a `Err` with an error message derived - /// from `E`'s `ToStr` implementation. - #[inline] - pub fn unwrap(self) -> T { - match self { - Ok(t) => t, - Err(e) => fail!("called `Result::unwrap()` on `Err` value: {}", - e.to_str()), - } - } + //////////////////////////////////////////////////////////////////////// + // Boolean operations on the values, eager and lazy + ///////////////////////////////////////////////////////////////////////// - /// Unwraps a result, yielding the content of an `Err`. - /// Fails if the value is a `Ok`. + /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`. #[inline] - pub fn unwrap_err(self) -> E { - self.expect_err("called `Result::unwrap_err()` on `Ok` value") - } - - /// Unwraps a result, yielding the content of an `Ok`. - /// Fails if the value is a `Err` with a custom failure message. - #[inline] - pub fn expect(self, reason: &str) -> T { - match self { - Ok(t) => t, - Err(_) => fail!("{}", reason.to_owned()), - } - } - - /// Unwraps a result, yielding the content of an `Err` - /// Fails if the value is a `Ok` with a custom failure message. - #[inline] - pub fn expect_err(self, reason: &str) -> E { - match self { - Err(e) => e, - Ok(_) => fail!("{}", reason.to_owned()), - } - } - - /// Call a method based on a previous result - /// - /// If `self` is `Ok` then the value is extracted and passed to `op` - /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is - /// `Err` then it is immediately returned. This function can be used to - /// compose the results of two functions. - /// - /// Example: - /// - /// let res = do read_file(file).map_move |buf| { - /// parse_bytes(buf) - /// } - #[inline] - pub fn map_move(self, op: &fn(T) -> U) -> Result { - match self { - Ok(t) => Ok(op(t)), - Err(e) => Err(e) - } - } - - /// Call a method based on a previous result - /// - /// If `self` is `Err` then the value is extracted and passed to `op` - /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is - /// `Ok` then it is immediately returned. This function can be used to pass - /// through a successful result while handling an error. - #[inline] - pub fn map_err_move(self, op: &fn(E) -> F) -> Result { - match self { - Ok(t) => Ok(t), - Err(e) => Err(op(e)) - } - } - - /// Call a method based on a previous result - /// - /// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`, - /// then `self` is returned. - #[inline] - pub fn and(self, res: Result) -> Result { + pub fn and(self, res: Result) -> Result { match self { Ok(_) => res, - Err(_) => self, + Err(e) => Err(e), } } - /// Call a method based on a previous result + /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`. /// - /// If `self` is `Ok` then the value is extracted and passed to `op` - /// whereupon `op`s result is returned. If `self` is `Err` then it is - /// immediately returned. This function can be used to compose the results - /// of two functions. - /// - /// Example: - /// - /// let res = do read_file(file) |buf| { - /// Ok(parse_bytes(buf)) - /// }; + /// This function can be used for control flow based on result values #[inline] pub fn and_then(self, op: &fn(T) -> Result) -> Result { match self { @@ -206,10 +215,7 @@ impl Result { } } - /// Call a method based on a previous result - /// - /// If `self` is `Ok`, then `self` is returned. If `self` is `Err` - /// then `res` is returned. + /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`. #[inline] pub fn or(self, res: Result) -> Result { match self { @@ -218,12 +224,9 @@ impl Result { } } - /// Call a function based on a previous result + /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`. /// - /// If `self` is `Err` then the value is extracted and passed to `op` - /// whereupon `op`s result is returned. if `self` is `Ok` then it is - /// immediately returned. This function can be used to pass through a - /// successful result while handling an error. + /// This function can be used for control flow based on result values #[inline] pub fn or_else(self, op: &fn(E) -> Result) -> Result { match self { @@ -231,45 +234,29 @@ impl Result { Err(e) => op(e), } } -} -impl Result { - /// Call a method based on a previous result + ///////////////////////////////////////////////////////////////////////// + // Common special cases + ///////////////////////////////////////////////////////////////////////// + + /// Get a reference to the value out of a successful result /// - /// If `self` is `Err` then the value is extracted and passed to `op` - /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is - /// `Ok` then it is immediately returned. This function can be used to pass - /// through a successful result while handling an error. + /// # Failure + /// + /// If the result is an error #[inline] - pub fn map_err(&self, op: &fn(&E) -> F) -> Result { + pub fn get_ref<'a>(&'a self) -> &'a T { match *self { - Ok(ref t) => Ok(t.clone()), - Err(ref e) => Err(op(e)) + Ok(ref t) => t, + Err(ref e) => fail!("called `Result::get_ref()` on `Err` value '{}'", + e.to_str()), } } } -impl Result { - /// Call a method based on a previous result - /// - /// If `self` is `Ok` then the value is extracted and passed to `op` - /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is - /// `Err` then it is immediately returned. This function can be used to - /// compose the results of two functions. - /// - /// Example: - /// - /// let res = do read_file(file).map |buf| { - /// parse_bytes(buf) - /// }; - #[inline] - pub fn map(&self, op: &fn(&T) -> U) -> Result { - match *self { - Ok(ref t) => Ok(op(t)), - Err(ref e) => Err(e.clone()) - } - } -} +///////////////////////////////////////////////////////////////////////////// +// Constructor extension trait +///////////////////////////////////////////////////////////////////////////// /// A generic trait for converting a value to a `Result` pub trait ToResult { @@ -289,36 +276,6 @@ pub trait AsResult { fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>; } -impl option::ToOption for Result { - #[inline] - fn to_option(&self) -> Option { - match *self { - Ok(ref t) => Some(t.clone()), - Err(_) => None, - } - } -} - -impl option::IntoOption for Result { - #[inline] - fn into_option(self) -> Option { - match self { - Ok(t) => Some(t), - Err(_) => None, - } - } -} - -impl option::AsOption for Result { - #[inline] - fn as_option<'a>(&'a self) -> Option<&'a T> { - match *self { - Ok(ref t) => Some(t), - Err(_) => None, - } - } -} - impl ToResult for Result { #[inline] fn to_result(&self) -> Result { self.clone() } @@ -339,42 +296,36 @@ impl AsResult for Result { } } -impl either::ToEither for Result { +///////////////////////////////////////////////////////////////////////////// +// Trait implementations +///////////////////////////////////////////////////////////////////////////// + +impl ToOption for Result { #[inline] - fn to_either(&self) -> either::Either { + fn to_option(&self) -> Option { match *self { - Ok(ref t) => either::Right(t.clone()), - Err(ref e) => either::Left(e.clone()), + Ok(ref t) => Some(t.clone()), + Err(_) => None, } } } -impl either::IntoEither for Result { +impl IntoOption for Result { #[inline] - fn into_either(self) -> either::Either { + fn into_option(self) -> Option { match self { - Ok(t) => either::Right(t), - Err(e) => either::Left(e), + Ok(t) => Some(t), + Err(_) => None, } } } -impl either::AsEither for Result { +impl AsOption for Result { #[inline] - fn as_either<'a>(&'a self) -> either::Either<&'a E, &'a T> { + fn as_option<'a>(&'a self) -> Option<&'a T> { match *self { - Ok(ref t) => either::Right(t), - Err(ref e) => either::Left(e), - } - } -} - -impl ToStr for Result { - #[inline] - fn to_str(&self) -> ~str { - match *self { - Ok(ref t) => format!("Ok({:s})", t.to_str()), - Err(ref e) => format!("Err({:s})", e.to_str()) + Ok(ref t) => Some(t), + Err(_) => None, } } } @@ -389,6 +340,10 @@ impl fmt::Default for Result { } } +///////////////////////////////////////////////////////////////////////////// +// Free functions +///////////////////////////////////////////////////////////////////////////// + /// Takes each element in the iterator: if it is an error, no further /// elements are taken, and the error is returned. /// Should no error occur, a vector containing the values of each Result @@ -450,17 +405,17 @@ pub fn fold_>>( fold(iterator, (), |_, _| ()) } +///////////////////////////////////////////////////////////////////////////// +// Tests +///////////////////////////////////////////////////////////////////////////// #[cfg(test)] mod tests { use super::*; - use either::{IntoEither, ToEither, AsEither}; - use either; use iter::range; use option::{IntoOption, ToOption, AsOption}; - use option; - use str::OwnedStr; + use option::{Some, None}; use vec::ImmutableVector; use to_str::ToStr; @@ -470,10 +425,10 @@ mod tests { #[test] pub fn test_and() { assert_eq!(op1().and(Ok(667)).unwrap(), 667); - assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad"); + assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad"); assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface"); - assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface"); + assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface"); } #[test] @@ -530,26 +485,14 @@ mod tests { #[test] pub fn test_impl_map() { - assert_eq!(Ok::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Ok(~"ba")); - assert_eq!(Err::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Err(~"a")); + assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab")); + assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a")); } #[test] pub fn test_impl_map_err() { - assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Ok(~"a")); - assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Err(~"ba")); - } - - #[test] - pub fn test_impl_map_move() { - assert_eq!(Ok::<~str, ~str>(~"a").map_move(|x| x + "b"), Ok(~"ab")); - assert_eq!(Err::<~str, ~str>(~"a").map_move(|x| x + "b"), Err(~"a")); - } - - #[test] - pub fn test_impl_map_err_move() { - assert_eq!(Ok::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Ok(~"a")); - assert_eq!(Err::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Err(~"ab")); + assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a")); + assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab")); } #[test] @@ -603,8 +546,8 @@ mod tests { let ok: Result = Ok(100); let err: Result = Err(404); - assert_eq!(ok.to_option(), option::Some(100)); - assert_eq!(err.to_option(), option::None); + assert_eq!(ok.to_option(), Some(100)); + assert_eq!(err.to_option(), None); } #[test] @@ -612,8 +555,8 @@ mod tests { let ok: Result = Ok(100); let err: Result = Err(404); - assert_eq!(ok.into_option(), option::Some(100)); - assert_eq!(err.into_option(), option::None); + assert_eq!(ok.into_option(), Some(100)); + assert_eq!(err.into_option(), None); } #[test] @@ -622,7 +565,7 @@ mod tests { let err: Result = Err(404); assert_eq!(ok.as_option().unwrap(), &100); - assert_eq!(err.as_option(), option::None); + assert_eq!(err.as_option(), None); } #[test] @@ -655,33 +598,6 @@ mod tests { assert_eq!(err.as_result(), Err(&x)); } - #[test] - pub fn test_to_either() { - let ok: Result = Ok(100); - let err: Result = Err(404); - - assert_eq!(ok.to_either(), either::Right(100)); - assert_eq!(err.to_either(), either::Left(404)); - } - - #[test] - pub fn test_into_either() { - let ok: Result = Ok(100); - let err: Result = Err(404); - - assert_eq!(ok.into_either(), either::Right(100)); - assert_eq!(err.into_either(), either::Left(404)); - } - - #[test] - pub fn test_as_either() { - let ok: Result = Ok(100); - let err: Result = Err(404); - - assert_eq!(ok.as_either().unwrap_right(), &100); - assert_eq!(err.as_either().unwrap_left(), &404); - } - #[test] pub fn test_to_str() { let ok: Result = Ok(100); diff --git a/src/libstd/rt/io/stdio.rs b/src/libstd/rt/io/stdio.rs index 1284ab73656..fb1a3fac8d5 100644 --- a/src/libstd/rt/io/stdio.rs +++ b/src/libstd/rt/io/stdio.rs @@ -208,7 +208,7 @@ impl Reader for StdReader { fn read(&mut self, buf: &mut [u8]) -> Option { let ret = match self.inner { TTY(ref mut tty) => tty.read(buf), - File(ref mut file) => file.read(buf).map_move(|i| i as uint), + File(ref mut file) => file.read(buf).map(|i| i as uint), }; match ret { Ok(amt) => Some(amt as uint), diff --git a/src/libstd/std.rs b/src/libstd/std.rs index df6c47a8492..018180c85b7 100644 --- a/src/libstd/std.rs +++ b/src/libstd/std.rs @@ -8,45 +8,40 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -# The Rust standard library - -The Rust standard library is a group of interrelated modules defining -the core language traits, operations on built-in data types, collections, -platform abstractions, the task scheduler, runtime support for language -features and other common functionality. - -`std` includes modules corresponding to each of the integer types, -each of the floating point types, the `bool` type, tuples, characters, -strings (`str`), vectors (`vec`), managed boxes (`managed`), owned -boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`). -Additionally, `std` provides pervasive types (`option` and `result`), -task creation and communication primitives (`task`, `comm`), platform -abstractions (`os` and `path`), basic I/O abstractions (`io`), common -traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings -to the C standard library (`libc`). - -# Standard library injection and the Rust prelude - -`std` is imported at the topmost level of every crate by default, as -if the first line of each crate was - - extern mod std; - -This means that the contents of std can be accessed from any context -with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, -etc. - -Additionally, `std` contains a `prelude` module that reexports many of the -most common types, traits and functions. The contents of the prelude are -imported into every *module* by default. Implicitly, all modules behave as if -they contained the following prologue: - - use std::prelude::*; - -*/ - +//! # The Rust standard library +//! +//! The Rust standard library is a group of interrelated modules defining +//! the core language traits, operations on built-in data types, collections, +//! platform abstractions, the task scheduler, runtime support for language +//! features and other common functionality. +//! +//! `std` includes modules corresponding to each of the integer types, +//! each of the floating point types, the `bool` type, tuples, characters, +//! strings (`str`), vectors (`vec`), managed boxes (`managed`), owned +//! boxes (`owned`), and unsafe and borrowed pointers (`ptr`, `borrowed`). +//! Additionally, `std` provides pervasive types (`option` and `result`), +//! task creation and communication primitives (`task`, `comm`), platform +//! abstractions (`os` and `path`), basic I/O abstractions (`io`), common +//! traits (`kinds`, `ops`, `cmp`, `num`, `to_str`), and complete bindings +//! to the C standard library (`libc`). +//! +//! # Standard library injection and the Rust prelude +//! +//! `std` is imported at the topmost level of every crate by default, as +//! if the first line of each crate was +//! +//! extern mod std; +//! +//! This means that the contents of std can be accessed from any context +//! with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, +//! etc. +//! +//! Additionally, `std` contains a `prelude` module that reexports many of the +//! most common types, traits and functions. The contents of the prelude are +//! imported into every *module* by default. Implicitly, all modules behave as if +//! they contained the following prologue: +//! +//! use std::prelude::*; #[link(name = "std", vers = "0.9-pre", @@ -97,6 +92,7 @@ pub mod linkhack { pub mod prelude; + /* Primitive types */ #[path = "num/int_macros.rs"] mod int_macros; @@ -158,6 +154,7 @@ pub mod container; pub mod default; pub mod any; + /* Common data structures */ pub mod option; @@ -198,11 +195,13 @@ pub mod util; pub mod routine; pub mod mem; + /* Unsupported interfaces */ // Private APIs pub mod unstable; + /* For internal use, not exported */ mod unicode; diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs index dfe4abe54e5..c27f6e3d086 100644 --- a/src/libstd/unit.rs +++ b/src/libstd/unit.rs @@ -8,11 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - -Functions for the unit type. - -*/ +//! Functions for the unit type. #[cfg(not(test))] use prelude::*; diff --git a/src/test/run-fail/result-get-fail.rs b/src/test/run-fail/result-get-fail.rs index 81eed9267ab..027faadecad 100644 --- a/src/test/run-fail/result-get-fail.rs +++ b/src/test/run-fail/result-get-fail.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:called `Result::unwrap()` on `Err` value: kitty +// error-pattern:called `Result::unwrap()` on `Err` value 'kitty' use std::result;