diff options
| author | bors <bors@rust-lang.org> | 2013-07-28 00:19:21 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-28 00:19:21 -0700 |
| commit | 20454da2db9903688dfd60b826cc704de79767bc (patch) | |
| tree | a20efcf40ca3c0473aca0b8c42383cd0bcf65ce1 /src/libstd | |
| parent | 9325535b41fa5a7cfac697e86ae86bd1384542e6 (diff) | |
| parent | b147d70b08f93ea0a13a5331f413d547819b2f4c (diff) | |
| download | rust-20454da2db9903688dfd60b826cc704de79767bc.tar.gz rust-20454da2db9903688dfd60b826cc704de79767bc.zip | |
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.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/io.rs | 66 | ||||
| -rw-r--r-- | src/libstd/option.rs | 228 | ||||
| -rw-r--r-- | src/libstd/result.rs | 436 |
3 files changed, 342 insertions, 388 deletions
diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 05a5184ccba..761d07da805 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -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 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 cast; use path::Path; -use ops::Drop; -use iterator::IteratorUtil; 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!() } } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index eb3f227562a..6e4880550eb 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -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, + } -#[test] -fn test_unwrap_resource() { - struct R { - i: @mut int, - } + #[unsafe_destructor] + impl ::ops::Drop for R { + fn drop(&self) { *(self.i) += 1; } + } - #[unsafe_destructor] - impl ::ops::Drop for R { - fn drop(&self) { *(self.i) += 1; } - } + fn R(i: @mut int) -> R { + R { + i: i + } + } - fn R(i: @mut int) -> R { - R { - i: i + let i = @mut 0; + { + let x = R(i); + let opt = Some(x); + let _y = opt.unwrap(); } + assert_eq!(*i, 1); } - let i = @mut 0; - { - let x = R(i); - let opt = Some(x); - let _y = opt.unwrap(); + #[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); } - 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(); + #[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); } - 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 - } + #[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()); } - 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_iter() { + let val = 5; -#[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()); -} + let x = Some(val); + let mut it = x.iter(); -#[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()); -} + 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; + #[test] + fn test_mut_iter() { + let val = 5; + let new_val = 11; - let mut x = Some(val); - let mut it = x.mut_iter(); + let mut x = Some(val); + let mut it = x.mut_iter(); - assert_eq!(it.size_hint(), (1, Some(1))); + 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)); + match it.next() { + Some(interior) => { + assert_eq!(*interior, val); + *interior = new_val; + assert_eq!(x, Some(new_val)); + } + None => assert!(false), } - None => assert!(false), - } - assert_eq!(it.size_hint(), (0, Some(0))); - assert!(it.next().is_none()); + assert_eq!(it.size_hint(), (0, Some(0))); + assert!(it.next().is_none()); + } } diff --git a/src/libstd/result.rs b/src/libstd/result.rs index acc4ece8fd5..c045c191488 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -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 to_either(self)-> either::Either<E, T>{ + match self { + Ok(t) => either::Right(t), + Err(e) => either::Left(e), + } } -} -impl<T, E> Result<T, E> { + /** + * 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 { get_ref(self) } + 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 { is_ok(self) } + 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 { is_err(self) } + 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)) { iter(self, f) } + 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)) { iter_err(self, f) } + 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 { unwrap(self) } + 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 { unwrap_err(self) } + 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> { - chain(self, op) + 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> { - chain_err(self, op) + 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)); + } } |
