auto merge of #8069 : erickt/rust/maikklein, r=erickt

Good evening,

This is a superset of @MaikKlein's #7969 commit, that I've fixed up to compile. I had a couple commits I wanted to do on top of @MaikKlein's work that I didn't want to bitrot.
This commit is contained in:
bors 2013-07-28 00:19:21 -07:00
commit 20454da2db
15 changed files with 410 additions and 467 deletions

View File

@ -1867,27 +1867,26 @@ mod tests {
col: 8u,
msg: @~"EOF while parsing object"}));
assert_eq!(result::unwrap(from_str("{}")), mk_object([]));
assert_eq!(result::unwrap(from_str("{\"a\": 3}")),
assert_eq!(from_str("{}").unwrap(), mk_object([]));
assert_eq!(from_str("{\"a\": 3}").unwrap(),
mk_object([(~"a", Number(3.0f))]));
assert_eq!(result::unwrap(from_str(
"{ \"a\": null, \"b\" : true }")),
assert_eq!(from_str(
"{ \"a\": null, \"b\" : true }").unwrap(),
mk_object([
(~"a", Null),
(~"b", Boolean(true))]));
assert_eq!(result::unwrap(
from_str("\n{ \"a\": null, \"b\" : true }\n")),
assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(),
mk_object([
(~"a", Null),
(~"b", Boolean(true))]));
assert_eq!(result::unwrap(from_str(
"{\"a\" : 1.0 ,\"b\": [ true ]}")),
assert_eq!(from_str(
"{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
mk_object([
(~"a", Number(1.0)),
(~"b", List(~[Boolean(true)]))
]));
assert_eq!(result::unwrap(from_str(
assert_eq!(from_str(
~"{" +
"\"a\": 1.0, " +
"\"b\": [" +
@ -1895,7 +1894,7 @@ mod tests {
"\"foo\\nbar\", " +
"{ \"c\": {\"d\": null} } " +
"]" +
"}")),
"}").unwrap(),
mk_object([
(~"a", Number(1.0f)),
(~"b", List(~[

View File

@ -1132,13 +1132,13 @@ mod tests {
assert!(test("6", "%w"));
assert!(test("2009", "%Y"));
assert!(test("09", "%y"));
assert!(result::unwrap(strptime("UTC", "%Z")).tm_zone ==
assert!(strptime("UTC", "%Z").unwrap().tm_zone ==
~"UTC");
assert!(result::unwrap(strptime("PST", "%Z")).tm_zone ==
assert!(strptime("PST", "%Z").unwrap().tm_zone ==
~"");
assert!(result::unwrap(strptime("-0000", "%z")).tm_gmtoff ==
assert!(strptime("-0000", "%z").unwrap().tm_gmtoff ==
0);
assert!(result::unwrap(strptime("-0800", "%z")).tm_gmtoff ==
assert!(strptime("-0800", "%z").unwrap().tm_gmtoff ==
0);
assert!(test("%", "%%"));

View File

@ -22,7 +22,6 @@ use std::cell::Cell;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::either::{Either, Left, Right};
use std::io;
use std::result;
use std::run;
use std::task;
@ -208,7 +207,7 @@ fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
// FIXME(#5121)
fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
do io::with_str_reader(s) |rdr| {
let j = result::unwrap(json::from_reader(rdr));
let j = json::from_reader(rdr).unwrap();
let mut decoder = json::Decoder(j);
Decodable::decode(&mut decoder)
}

View File

@ -147,7 +147,7 @@ pub fn get_rustpkg_root() -> Result<Path, ~str> {
}
pub fn get_rustpkg_root_nearest() -> Result<Path, ~str> {
do result::chain(get_rustpkg_root()) |p| {
do get_rustpkg_root().chain |p| {
let cwd = os::getcwd();
let cwd_rustpkg = cwd.push(".rustpkg");
let rustpkg_is_non_root_file =
@ -173,13 +173,13 @@ pub fn get_rustpkg_root_nearest() -> Result<Path, ~str> {
}
fn get_rustpkg_lib_path() -> Result<Path, ~str> {
do result::chain(get_rustpkg_root()) |p| {
do get_rustpkg_root().chain |p| {
result::Ok(p.push(libdir()))
}
}
fn get_rustpkg_lib_path_nearest() -> Result<Path, ~str> {
do result::chain(get_rustpkg_root_nearest()) |p| {
do get_rustpkg_root_nearest().chain |p| {
result::Ok(p.push(libdir()))
}
}

View File

@ -138,7 +138,7 @@ fn config_from_opts(
let config = default_config(input_crate);
let result = result::Ok(config);
let result = do result::chain(result) |config| {
let result = do result.chain |config| {
let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
let output_dir = output_dir.map(|s| Path(*s));
result::Ok(Config {
@ -146,14 +146,10 @@ fn config_from_opts(
.. config
})
};
let result = do result::chain(result) |config| {
let output_format = getopts::opt_maybe_str(
matches, opt_output_format());
do output_format.map_default(result::Ok(config.clone()))
|output_format| {
do result::chain(parse_output_format(*output_format))
|output_format| {
let result = do result.chain |config| {
let output_format = getopts::opt_maybe_str(matches, opt_output_format());
do output_format.map_default(result::Ok(config.clone())) |output_format| {
do parse_output_format(*output_format).chain |output_format| {
result::Ok(Config {
output_format: output_format,
.. config.clone()
@ -161,13 +157,11 @@ fn config_from_opts(
}
}
};
let result = do result::chain(result) |config| {
let result = do result.chain |config| {
let output_style =
getopts::opt_maybe_str(matches, opt_output_style());
do output_style.map_default(result::Ok(config.clone()))
|output_style| {
do result::chain(parse_output_style(*output_style))
|output_style| {
do output_style.map_default(result::Ok(config.clone())) |output_style| {
do parse_output_style(*output_style).chain |output_style| {
result::Ok(Config {
output_style: output_style,
.. config.clone()
@ -176,11 +170,11 @@ fn config_from_opts(
}
};
let process_output = Cell::new(process_output);
let result = do result::chain(result) |config| {
let result = do result.chain |config| {
let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
let pandoc_cmd = maybe_find_pandoc(
&config, pandoc_cmd, process_output.take());
do result::chain(pandoc_cmd) |pandoc_cmd| {
do pandoc_cmd.chain |pandoc_cmd| {
result::Ok(Config {
pandoc_cmd: pandoc_cmd,
.. config.clone()

View File

@ -62,9 +62,7 @@ fn git_repo_pkg() -> PkgId {
}
fn writeFile(file_path: &Path, contents: &str) {
let out: @io::Writer =
result::unwrap(io::file_writer(file_path,
[io::Create, io::Truncate]));
let out = io::file_writer(file_path, [io::Create, io::Truncate]).unwrap();
out.write_line(contents);
}

View File

@ -46,28 +46,26 @@ implement `Reader` and `Writer`, where appropriate.
#[allow(missing_doc)];
use result::Result;
use cast;
use clone::Clone;
use container::Container;
use int;
use libc;
use libc::{c_int, c_long, c_void, size_t, ssize_t};
use libc::consts::os::posix88::*;
use num;
use os;
use cast;
use path::Path;
use ops::Drop;
use iterator::IteratorUtil;
use libc::consts::os::posix88::*;
use libc::{c_int, c_long, c_void, size_t, ssize_t};
use libc;
use num;
use ops::Drop;
use os;
use path::Path;
use ptr;
use result;
use str;
use result::{Result, Ok, Err};
use str::{StrSlice, OwnedStr};
use str;
use to_str::ToStr;
use uint;
use vec;
use vec::{MutableVector, ImmutableVector, OwnedVector, OwnedCopyableVector, CopyableVector};
use vec;
#[allow(non_camel_case_types)] // not sure what to do about this
pub type fd_t = c_int;
@ -1038,9 +1036,9 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
};
if f as uint == 0u {
result::Err(~"error opening " + path.to_str())
Err(~"error opening " + path.to_str())
} else {
result::Ok(FILE_reader(f, true))
Ok(FILE_reader(f, true))
}
}
@ -1287,10 +1285,9 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
}
};
if fd < (0 as c_int) {
result::Err(fmt!("error opening %s: %s", path.to_str(),
os::last_os_error()))
Err(fmt!("error opening %s: %s", path.to_str(), os::last_os_error()))
} else {
result::Ok(fd_writer(fd, true))
Ok(fd_writer(fd, true))
}
}
@ -1559,7 +1556,7 @@ impl<T:Writer> WriterUtil for T {
}
pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
mk_file_writer(path, flags).chain(|w| result::Ok(w))
mk_file_writer(path, flags).chain(|w| Ok(w))
}
@ -1572,9 +1569,9 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
}
};
return if f as uint == 0u {
result::Err(~"error opening " + path.to_str())
Err(~"error opening " + path.to_str())
} else {
result::Ok(FILE_writer(f, true))
Ok(FILE_writer(f, true))
}
}
}
@ -1726,21 +1723,21 @@ pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
}
pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
result::chain(read_whole_file(file), |bytes| {
do read_whole_file(file).chain |bytes| {
if str::is_utf8(bytes) {
result::Ok(str::from_bytes(bytes))
Ok(str::from_bytes(bytes))
} else {
result::Err(file.to_str() + " is not UTF-8")
Err(file.to_str() + " is not UTF-8")
}
})
}
}
// FIXME (#2004): implement this in a low-level way. Going through the
// abstractions is pointless.
pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
result::chain(file_reader(file), |rdr| {
result::Ok(rdr.read_whole_stream())
})
do file_reader(file).chain |rdr| {
Ok(rdr.read_whole_stream())
}
}
// fsync related
@ -1839,6 +1836,7 @@ mod tests {
use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
use io;
use path::Path;
use result::{Ok, Err};
use result;
use u64;
use vec;
@ -1851,12 +1849,10 @@ mod tests {
~"A hoopy frood who really knows where his towel is.";
debug!(frood.clone());
{
let out: @io::Writer =
result::unwrap(
io::file_writer(tmpfile, [io::Create, io::Truncate]));
let out = io::file_writer(tmpfile, [io::Create, io::Truncate]).unwrap();
out.write_str(frood);
}
let inp: @io::Reader = result::unwrap(io::file_reader(tmpfile));
let inp = io::file_reader(tmpfile).unwrap();
let frood2: ~str = inp.read_c_str();
debug!(frood2.clone());
assert_eq!(frood, frood2);
@ -1941,10 +1937,10 @@ mod tests {
#[test]
fn file_reader_not_exist() {
match io::file_reader(&Path("not a file")) {
result::Err(e) => {
Err(e) => {
assert_eq!(e, ~"error opening not a file");
}
result::Ok(_) => fail!()
Ok(_) => fail!()
}
}
@ -1982,20 +1978,20 @@ mod tests {
#[test]
fn file_writer_bad_name() {
match io::file_writer(&Path("?/?"), []) {
result::Err(e) => {
Err(e) => {
assert!(e.starts_with("error opening"));
}
result::Ok(_) => fail!()
Ok(_) => fail!()
}
}
#[test]
fn buffered_file_writer_bad_name() {
match io::buffered_file_writer(&Path("?/?")) {
result::Err(e) => {
Err(e) => {
assert!(e.starts_with("error opening"));
}
result::Ok(_) => fail!()
Ok(_) => fail!()
}
}

View File

@ -271,7 +271,7 @@ impl<T> Option<T> {
pub fn get_ref<'a>(&'a self) -> &'a T {
match *self {
Some(ref x) => x,
None => fail!("option::get_ref None")
None => fail!("option::get_ref `None`"),
}
}
@ -293,7 +293,7 @@ impl<T> Option<T> {
pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
match *self {
Some(ref mut x) => x,
None => fail!("option::get_mut_ref None")
None => fail!("option::get_mut_ref `None`"),
}
}
@ -317,7 +317,7 @@ impl<T> Option<T> {
*/
match self {
Some(x) => x,
None => fail!("option::unwrap None")
None => fail!("option::unwrap `None`"),
}
}
@ -331,7 +331,7 @@ impl<T> Option<T> {
*/
#[inline]
pub fn take_unwrap(&mut self) -> T {
if self.is_none() { fail!("option::take_unwrap None") }
if self.is_none() { fail!("option::take_unwrap `None`") }
self.take().unwrap()
}
@ -369,7 +369,7 @@ impl<T> Option<T> {
pub fn get(self) -> T {
match self {
Some(x) => return x,
None => fail!("option::get None")
None => fail!("option::get `None`")
}
}
@ -379,7 +379,7 @@ impl<T> Option<T> {
match self { Some(x) => x, None => def }
}
/// Applies a function zero or more times until the result is None.
/// Applies a function zero or more times until the result is `None`.
#[inline]
pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
let mut opt = self;
@ -441,134 +441,140 @@ impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
}
}
#[test]
fn test_unwrap_ptr() {
unsafe {
let x = ~0;
let addr_x: *int = ::cast::transmute(&*x);
#[cfg(test)]
mod tests {
use super::*;
use util;
#[test]
fn test_unwrap_ptr() {
unsafe {
let x = ~0;
let addr_x: *int = ::cast::transmute(&*x);
let opt = Some(x);
let y = opt.unwrap();
let addr_y: *int = ::cast::transmute(&*y);
assert_eq!(addr_x, addr_y);
}
}
#[test]
fn test_unwrap_str() {
let x = ~"test";
let addr_x = x.as_imm_buf(|buf, _len| buf);
let opt = Some(x);
let y = opt.unwrap();
let addr_y: *int = ::cast::transmute(&*y);
let addr_y = y.as_imm_buf(|buf, _len| buf);
assert_eq!(addr_x, addr_y);
}
}
#[test]
fn test_unwrap_str() {
let x = ~"test";
let addr_x = x.as_imm_buf(|buf, _len| buf);
let opt = Some(x);
let y = opt.unwrap();
let addr_y = y.as_imm_buf(|buf, _len| buf);
assert_eq!(addr_x, addr_y);
}
#[test]
fn test_unwrap_resource() {
struct R {
i: @mut int,
}
#[unsafe_destructor]
impl ::ops::Drop for R {
fn drop(&self) { *(self.i) += 1; }
}
fn R(i: @mut int) -> R {
R {
i: i
#[test]
fn test_unwrap_resource() {
struct R {
i: @mut int,
}
}
let i = @mut 0;
{
let x = R(i);
let opt = Some(x);
let _y = opt.unwrap();
}
assert_eq!(*i, 1);
}
#[test]
fn test_option_dance() {
let x = Some(());
let mut y = Some(5);
let mut y2 = 0;
for x.iter().advance |_x| {
y2 = y.take_unwrap();
}
assert_eq!(y2, 5);
assert!(y.is_none());
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
let mut y = Some(util::NonCopyable);
let _y2 = y.take_unwrap();
let _y3 = y.take_unwrap();
}
#[test]
fn test_option_while_some() {
let mut i = 0;
do Some(10).while_some |j| {
i += 1;
if (j > 0) {
Some(j-1)
} else {
None
#[unsafe_destructor]
impl ::ops::Drop for R {
fn drop(&self) { *(self.i) += 1; }
}
}
assert_eq!(i, 11);
}
#[test]
fn test_get_or_zero() {
let some_stuff = Some(42);
assert_eq!(some_stuff.get_or_zero(), 42);
let no_stuff: Option<int> = None;
assert_eq!(no_stuff.get_or_zero(), 0);
}
#[test]
fn test_filtered() {
let some_stuff = Some(42);
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
assert_eq!(some_stuff.get(), 42);
assert!(modified_stuff.is_none());
}
#[test]
fn test_iter() {
let val = 5;
let x = Some(val);
let mut it = x.iter();
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next(), Some(&val));
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
#[test]
fn test_mut_iter() {
let val = 5;
let new_val = 11;
let mut x = Some(val);
let mut it = x.mut_iter();
assert_eq!(it.size_hint(), (1, Some(1)));
match it.next() {
Some(interior) => {
assert_eq!(*interior, val);
*interior = new_val;
assert_eq!(x, Some(new_val));
fn R(i: @mut int) -> R {
R {
i: i
}
}
None => assert!(false),
let i = @mut 0;
{
let x = R(i);
let opt = Some(x);
let _y = opt.unwrap();
}
assert_eq!(*i, 1);
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
#[test]
fn test_option_dance() {
let x = Some(());
let mut y = Some(5);
let mut y2 = 0;
for x.iter().advance |_x| {
y2 = y.take_unwrap();
}
assert_eq!(y2, 5);
assert!(y.is_none());
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
let mut y = Some(util::NonCopyable);
let _y2 = y.take_unwrap();
let _y3 = y.take_unwrap();
}
#[test]
fn test_option_while_some() {
let mut i = 0;
do Some(10).while_some |j| {
i += 1;
if (j > 0) {
Some(j-1)
} else {
None
}
}
assert_eq!(i, 11);
}
#[test]
fn test_get_or_zero() {
let some_stuff = Some(42);
assert_eq!(some_stuff.get_or_zero(), 42);
let no_stuff: Option<int> = None;
assert_eq!(no_stuff.get_or_zero(), 0);
}
#[test]
fn test_filtered() {
let some_stuff = Some(42);
let modified_stuff = some_stuff.filtered(|&x| {x < 10});
assert_eq!(some_stuff.get(), 42);
assert!(modified_stuff.is_none());
}
#[test]
fn test_iter() {
let val = 5;
let x = Some(val);
let mut it = x.iter();
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next(), Some(&val));
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
#[test]
fn test_mut_iter() {
let val = 5;
let new_val = 11;
let mut x = Some(val);
let mut it = x.mut_iter();
assert_eq!(it.size_hint(), (1, Some(1)));
match it.next() {
Some(interior) => {
assert_eq!(*interior, val);
*interior = new_val;
assert_eq!(x, Some(new_val));
}
None => assert!(false),
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
}

View File

@ -15,7 +15,6 @@
use clone::Clone;
use cmp::Eq;
use either;
use either::Either;
use iterator::IteratorUtil;
use option::{None, Option, Some};
use vec;
@ -31,253 +30,215 @@ pub enum Result<T, U> {
Err(U)
}
/**
* Get the value out of a successful result
*
* # Failure
*
* If the result is an error
*/
#[inline]
pub fn get<T:Clone,U>(res: &Result<T, U>) -> T {
match *res {
Ok(ref t) => (*t).clone(),
Err(ref the_err) =>
fail!("get called on error result: %?", *the_err)
}
}
/**
* Get a reference to the value out of a successful result
*
* # Failure
*
* If the result is an error
*/
#[inline]
pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
match *res {
Ok(ref t) => t,
Err(ref the_err) =>
fail!("get_ref called on error result: %?", *the_err)
}
}
/**
* Get the value out of an error result
*
* # Failure
*
* If the result is not an error
*/
#[inline]
pub fn get_err<T, U: Clone>(res: &Result<T, U>) -> U {
match *res {
Err(ref u) => (*u).clone(),
Ok(_) => fail!("get_err called on ok result")
}
}
/// Returns true if the result is `ok`
#[inline]
pub fn is_ok<T, U>(res: &Result<T, U>) -> bool {
match *res {
Ok(_) => true,
Err(_) => false
}
}
/// Returns true if the result is `err`
#[inline]
pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
!is_ok(res)
}
/**
* Convert to the `either` type
*
* `ok` result variants are converted to `either::right` variants, `err`
* result variants are converted to `either::left`.
*/
#[inline]
pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
-> Either<T, U> {
match *res {
Ok(ref res) => either::Right((*res).clone()),
Err(ref fail_) => either::Left((*fail_).clone())
}
}
/**
* Call a function based on a previous result
*
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
* `op`s result is returned. if `res` is `err` then it is immediately
* returned. This function can be used to compose the results of two
* functions.
*
* Example:
*
* let res = chain(read_file(file)) { |buf|
* ok(parse_bytes(buf))
* }
*/
#[inline]
pub fn chain<T, U, V>(res: Result<T, V>, op: &fn(T)
-> Result<U, V>) -> Result<U, V> {
match res {
Ok(t) => op(t),
Err(e) => Err(e)
}
}
/**
* Call a function based on a previous result
*
* If `res` is `err` then the value is extracted and passed to `op`
* whereupon `op`s result is returned. if `res` 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 chain_err<T, U, V>(
res: Result<T, V>,
op: &fn(t: V) -> Result<T, U>)
-> Result<T, U> {
match res {
Ok(t) => Ok(t),
Err(v) => op(v)
}
}
/**
* Call a function based on a previous result
*
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
* `op`s result is returned. if `res` is `err` then it is immediately
* returned. This function can be used to compose the results of two
* functions.
*
* Example:
*
* iter(read_file(file)) { |buf|
* print_buf(buf)
* }
*/
#[inline]
pub fn iter<T, E>(res: &Result<T, E>, f: &fn(&T)) {
match *res {
Ok(ref t) => f(t),
Err(_) => ()
}
}
/**
* Call a function based on a previous result
*
* If `res` is `err` then the value is extracted and passed to `op` whereupon
* `op`s result is returned. if `res` 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 iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
match *res {
Ok(_) => (),
Err(ref e) => f(e)
}
}
/**
* Call a function based on a previous result
*
* If `res` is `ok` then the value is extracted and passed to `op` whereupon
* `op`s result is wrapped in `ok` and returned. if `res` is `err` then it is
* immediately returned. This function can be used to compose the results of
* two functions.
*
* Example:
*
* let res = map(read_file(file)) { |buf|
* parse_bytes(buf)
* }
*/
#[inline]
pub fn map<T, E: Clone, U: Clone>(res: &Result<T, E>, op: &fn(&T) -> U)
-> Result<U, E> {
match *res {
Ok(ref t) => Ok(op(t)),
Err(ref e) => Err((*e).clone())
}
}
/**
* Call a function based on a previous result
*
* If `res` is `err` then the value is extracted and passed to `op` whereupon
* `op`s result is wrapped in an `err` and returned. if `res` 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<T:Clone,E,F:Clone>(res: &Result<T, E>, op: &fn(&E) -> F)
-> Result<T, F> {
match *res {
Ok(ref t) => Ok((*t).clone()),
Err(ref e) => Err(op(e))
}
}
impl<T, E> Result<T, E> {
/**
* Convert to the `either` type
*
* `Ok` result variants are converted to `either::Right` variants, `Err`
* result variants are converted to `either::Left`.
*/
#[inline]
pub fn get_ref<'a>(&'a self) -> &'a T { get_ref(self) }
#[inline]
pub fn is_ok(&self) -> bool { is_ok(self) }
#[inline]
pub fn is_err(&self) -> bool { is_err(self) }
#[inline]
pub fn iter(&self, f: &fn(&T)) { iter(self, f) }
#[inline]
pub fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) }
#[inline]
pub fn unwrap(self) -> T { unwrap(self) }
#[inline]
pub fn unwrap_err(self) -> E { unwrap_err(self) }
#[inline]
pub fn chain<U>(self, op: &fn(T) -> Result<U,E>) -> Result<U,E> {
chain(self, op)
pub fn to_either(self)-> either::Either<E, T>{
match self {
Ok(t) => either::Right(t),
Err(e) => either::Left(e),
}
}
/**
* Get a reference to the value out of a successful result
*
* # Failure
*
* If the result is an error
*/
#[inline]
pub fn chain_err<F>(self, op: &fn(E) -> Result<T,F>) -> Result<T,F> {
chain_err(self, op)
pub fn get_ref<'a>(&'a self) -> &'a T {
match *self {
Ok(ref t) => t,
Err(ref e) => fail!("get_ref called on `Err` result: %?", *e),
}
}
/// Returns true if the result is `Ok`
#[inline]
pub fn is_ok(&self) -> bool {
match *self {
Ok(_) => true,
Err(_) => false
}
}
/// Returns true if the result is `Err`
#[inline]
pub fn is_err(&self) -> bool {
!self.is_ok()
}
/**
* 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 returned. if `self` is `Err` then it is
* immediately returned. This function can be used to compose the results
* of two functions.
*
* Example:
*
* do read_file(file).iter |buf| {
* print_buf(buf)
* }
*/
#[inline]
pub fn iter(&self, f: &fn(&T)) {
match *self {
Ok(ref t) => f(t),
Err(_) => (),
}
}
/**
* 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.
*/
#[inline]
pub fn iter_err(&self, f: &fn(&E)) {
match *self {
Ok(_) => (),
Err(ref e) => f(e),
}
}
/// Unwraps a result, assuming it is an `Ok(T)`
#[inline]
pub fn unwrap(self) -> T {
match self {
Ok(t) => t,
Err(_) => fail!("unwrap called on an `Err` result"),
}
}
/// Unwraps a result, assuming it is an `Err(U)`
#[inline]
pub fn unwrap_err(self) -> E {
match self {
Err(e) => e,
Ok(_) => fail!("unwrap called on an `Ok` 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 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))
* };
*/
#[inline]
pub fn chain<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
match self {
Ok(t) => op(t),
Err(e) => Err(e),
}
}
/**
* Call a function 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.
*/
#[inline]
pub fn chain_err<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
match self {
Ok(t) => Ok(t),
Err(e) => op(e),
}
}
}
impl<T:Clone,E> Result<T, E> {
impl<T: Clone, E> Result<T, E> {
/**
* Get the value out of a successful result
*
* # Failure
*
* If the result is an error
*/
#[inline]
pub fn get(&self) -> T { get(self) }
pub fn get(&self) -> T {
match *self {
Ok(ref t) => t.clone(),
Err(ref e) => fail!("get called on `Err` result: %?", *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<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
map_err(self, op)
match *self {
Ok(ref t) => Ok(t.clone()),
Err(ref e) => Err(op(e))
}
}
}
impl<T, E:Clone> Result<T, E> {
impl<T, E: Clone> Result<T, E> {
/**
* Get the value out of an error result
*
* # Failure
*
* If the result is not an error
*/
#[inline]
pub fn get_err(&self) -> E { get_err(self) }
pub fn get_err(&self) -> E {
match *self {
Err(ref e) => e.clone(),
Ok(_) => fail!("get_err called on `Ok` 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<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
map(self, op)
match *self {
Ok(ref t) => Ok(op(t)),
Err(ref e) => Err(e.clone())
}
}
}
@ -291,8 +252,8 @@ impl<T, E:Clone> Result<T, E> {
* checking for overflow:
*
* fn inc_conditionally(x: uint) -> result<uint,str> {
* if x == uint::max_value { return err("overflow"); }
* else { return ok(x+1u); }
* if x == uint::max_value { return Err("overflow"); }
* else { return Ok(x+1u); }
* }
* map(~[1u, 2u, 3u], inc_conditionally).chain {|incd|
* assert!(incd == ~[2u, 3u, 4u]);
@ -377,45 +338,27 @@ pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
return Ok(());
}
/// Unwraps a result, assuming it is an `ok(T)`
#[inline]
pub fn unwrap<T, U>(res: Result<T, U>) -> T {
match res {
Ok(t) => t,
Err(_) => fail!("unwrap called on an err result")
}
}
/// Unwraps a result, assuming it is an `err(U)`
#[inline]
pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
match res {
Err(u) => u,
Ok(_) => fail!("unwrap called on an ok result")
}
}
#[cfg(test)]
mod tests {
use result::{Err, Ok, Result, chain, get, get_err};
use result;
use super::*;
use either;
pub fn op1() -> result::Result<int, ~str> { result::Ok(666) }
pub fn op1() -> Result<int, ~str> { Ok(666) }
pub fn op2(i: int) -> result::Result<uint, ~str> {
result::Ok(i as uint + 1u)
pub fn op2(i: int) -> Result<uint, ~str> {
Ok(i as uint + 1u)
}
pub fn op3() -> result::Result<int, ~str> { result::Err(~"sadface") }
pub fn op3() -> Result<int, ~str> { Err(~"sadface") }
#[test]
pub fn chain_success() {
assert_eq!(get(&chain(op1(), op2)), 667u);
assert_eq!(op1().chain(op2).get(), 667u);
}
#[test]
pub fn chain_failure() {
assert_eq!(get_err(&chain(op3(), op2)), ~"sadface");
assert_eq!(op3().chain( op2).get_err(), ~"sadface");
}
#[test]
@ -456,4 +399,13 @@ mod tests {
let foo: Result<int, ()> = Ok(100);
assert_eq!(*foo.get_ref(), 100);
}
#[test]
pub fn test_to_either() {
let r: Result<int, ()> = Ok(100);
let err: Result<(), int> = Err(404);
assert_eq!(r.to_either(), either::Right(100));
assert_eq!(err.to_either(), either::Left(404));
}
}

View File

@ -75,7 +75,7 @@ fn read_line() {
.push_rel(&Path("src/test/bench/shootout-k-nucleotide.data"));
for int::range(0, 3) |_i| {
let reader = result::unwrap(io::file_reader(&path));
let reader = io::file_reader(&path).unwrap();
while !reader.eof() {
reader.read_line();
}

View File

@ -124,8 +124,8 @@ fn main() {
};
let writer = if os::getenv("RUST_BENCH").is_some() {
result::unwrap(io::file_writer(&Path("./shootout-fasta.data"),
[io::Truncate, io::Create]))
io::file_writer(&Path("./shootout-fasta.data"),
[io::Truncate, io::Create]).unwrap()
} else {
io::stdout()
};

View File

@ -161,7 +161,7 @@ fn main() {
// get to this massive data set, but include_bin! chokes on it (#2598)
let path = Path(env!("CFG_SRC_DIR"))
.push_rel(&Path("src/test/bench/shootout-k-nucleotide.data"));
result::unwrap(io::file_reader(&path))
io::file_reader(&path).unwrap()
} else {
io::stdin()
};

View File

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:get called on error result: ~"kitty"
// error-pattern:get called on `Err` result: ~"kitty"
use std::result;
fn main() {
error!(result::get(&result::Err::<int,~str>(~"kitty")));
error!(result::Err::<int,~str>(~"kitty").get());
}

View File

@ -16,7 +16,7 @@ use std::task;
fn adder(x: @int, y: @int) -> int { return *x + *y; }
fn failer() -> @int { fail!(); }
pub fn main() {
assert!(result::is_err(&task::try(|| {
assert!(task::try(|| {
adder(@2, failer()); ()
})));
}).is_err());
}

View File

@ -11,14 +11,13 @@
extern mod extra;
use std::result;
use extra::json;
use extra::serialize::Decodable;
trait JD : Decodable<json::Decoder> { }
fn exec<T: JD>() {
let doc = result::unwrap(json::from_str(""));
let doc = json::from_str("").unwrap();
let mut decoder = json::Decoder(doc);
let _v: T = Decodable::decode(&mut decoder);
fail!()