diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 3a6b1666c1e79..4fee64e630481 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -19,7 +19,7 @@ pub fn load_errors(testfile: &Path) -> ~[ExpectedError] { let mut rdr = BufferedReader::new(File::open(testfile).unwrap()); let mut line_num = 1u; for ln in rdr.lines() { - error_patterns.push_all_move(parse_expected(line_num, ln)); + error_patterns.push_all_move(parse_expected(line_num, ln.unwrap())); line_num += 1u; } return error_patterns; diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 7f8be5ff090e6..81b76f6b09a83 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -140,6 +140,7 @@ fn iter_header(testfile: &Path, it: |&str| -> bool) -> bool { // Assume that any directives will be found before the first // module or function. This doesn't seem to be an optimization // with a warm page cache. Maybe with a cold one. + let ln = ln.unwrap(); if ln.starts_with("fn") || ln.starts_with("mod") { return true; } else { if !(it(ln.trim())) { return false; } } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index fa122fa8c1160..3ae44e4a1b5ce 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -537,9 +537,9 @@ mod test { let in_buf = MemReader::new(bytes!("a\nb\nc").to_owned()); let mut reader = BufferedReader::with_capacity(2, in_buf); let mut it = reader.lines(); - assert_eq!(it.next(), Some(~"a\n")); - assert_eq!(it.next(), Some(~"b\n")); - assert_eq!(it.next(), Some(~"c")); + assert_eq!(it.next(), Some(Ok(~"a\n"))); + assert_eq!(it.next(), Some(Ok(~"b\n"))); + assert_eq!(it.next(), Some(Ok(~"c"))); assert_eq!(it.next(), None); } @@ -569,8 +569,8 @@ mod test { let buf = [195u8, 159u8, 'a' as u8]; let mut reader = BufferedReader::with_capacity(1, BufReader::new(buf)); let mut it = reader.chars(); - assert_eq!(it.next(), Some('ß')); - assert_eq!(it.next(), Some('a')); + assert_eq!(it.next(), Some(Ok('ß'))); + assert_eq!(it.next(), Some(Ok('a'))); assert_eq!(it.next(), None); } diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index 0424b7783cec9..f7cab755714f2 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -17,13 +17,15 @@ use container::Container; use iter::Iterator; -use option::Option; -use io::Reader; +use option::{Option, Some, None}; +use result::{Ok, Err}; +use io; +use io::{IoError, IoResult, Reader}; use vec::{OwnedVector, ImmutableVector}; use ptr::RawPtr; /// An iterator that reads a single byte on each iteration, -/// until `.read_byte()` returns `None`. +/// until `.read_byte()` returns `EndOfFile`. /// /// # Notes about the Iteration Protocol /// @@ -31,11 +33,10 @@ use ptr::RawPtr; /// an iteration, but continue to yield elements if iteration /// is attempted again. /// -/// # Failure +/// # Error /// -/// Raises the same conditions as the `read` method, for -/// each call to its `.next()` method. -/// Yields `None` if the condition is handled. +/// Any error other than `EndOfFile` that is produced by the underlying Reader +/// is returned by the iterator and should be handled by the caller. pub struct Bytes<'r, T> { priv reader: &'r mut T, } @@ -46,10 +47,14 @@ impl<'r, R: Reader> Bytes<'r, R> { } } -impl<'r, R: Reader> Iterator for Bytes<'r, R> { +impl<'r, R: Reader> Iterator> for Bytes<'r, R> { #[inline] - fn next(&mut self) -> Option { - self.reader.read_byte().ok() + fn next(&mut self) -> Option> { + match self.reader.read_byte() { + Ok(x) => Some(Ok(x)), + Err(IoError { kind: io::EndOfFile, .. }) => None, + Err(e) => Some(Err(e)) + } } } @@ -257,7 +262,7 @@ mod test { count: 0, }; let byte = reader.bytes().next(); - assert!(byte == Some(10)); + assert!(byte == Some(Ok(10))); } #[test] @@ -272,7 +277,7 @@ mod test { let mut reader = ErroringReader; let mut it = reader.bytes(); let byte = it.next(); - assert!(byte.is_none()); + assert!(byte.unwrap().is_err()); } #[test] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 1c10c7b61c364..26dcd0c077ce7 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -31,7 +31,7 @@ Some examples of obvious things you might want to do use std::io; for line in io::stdin().lines() { - print!("{}", line); + print!("{}", line.unwrap()); } ``` @@ -57,26 +57,26 @@ Some examples of obvious things you might want to do * Iterate over the lines of a file - ```rust + ```rust,no_run use std::io::BufferedReader; use std::io::File; let path = Path::new("message.txt"); let mut file = BufferedReader::new(File::open(&path)); for line in file.lines() { - print!("{}", line); + print!("{}", line.unwrap()); } ``` * Pull the lines of a file into a vector of strings - ```rust + ```rust,no_run use std::io::BufferedReader; use std::io::File; let path = Path::new("message.txt"); let mut file = BufferedReader::new(File::open(&path)); - let lines: ~[~str] = file.lines().collect(); + let lines: ~[~str] = file.lines().map(|x| x.unwrap()).collect(); ``` * Make a simple TCP client connection and request @@ -466,10 +466,8 @@ pub trait Reader { /// /// # Error /// - /// The iterator protocol causes all specifics about errors encountered to - /// be swallowed. All errors will be signified by returning `None` from the - /// iterator. If this is undesirable, it is recommended to use the - /// `read_byte` method. + /// Any error other than `EndOfFile` that is produced by the underlying Reader + /// is returned by the iterator and should be handled by the caller. fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> { extensions::Bytes::new(self) } @@ -986,7 +984,7 @@ pub trait Stream: Reader + Writer { } impl Stream for T {} /// An iterator that reads a line on each iteration, -/// until `.read_line()` returns `None`. +/// until `.read_line()` encounters `EndOfFile`. /// /// # Notes about the Iteration Protocol /// @@ -996,21 +994,24 @@ impl Stream for T {} /// /// # Error /// -/// This iterator will swallow all I/O errors, transforming `Err` values to -/// `None`. If errors need to be handled, it is recommended to use the -/// `read_line` method directly. +/// Any error other than `EndOfFile` that is produced by the underlying Reader +/// is returned by the iterator and should be handled by the caller. pub struct Lines<'r, T> { priv buffer: &'r mut T, } -impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> { - fn next(&mut self) -> Option<~str> { - self.buffer.read_line().ok() +impl<'r, T: Buffer> Iterator> for Lines<'r, T> { + fn next(&mut self) -> Option> { + match self.buffer.read_line() { + Ok(x) => Some(Ok(x)), + Err(IoError { kind: EndOfFile, ..}) => None, + Err(y) => Some(Err(y)) + } } } /// An iterator that reads a utf8-encoded character on each iteration, -/// until `.read_char()` returns `None`. +/// until `.read_char()` encounters `EndOfFile`. /// /// # Notes about the Iteration Protocol /// @@ -1020,16 +1021,19 @@ impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> { /// /// # Error /// -/// This iterator will swallow all I/O errors, transforming `Err` values to -/// `None`. If errors need to be handled, it is recommended to use the -/// `read_char` method directly. +/// Any error other than `EndOfFile` that is produced by the underlying Reader +/// is returned by the iterator and should be handled by the caller. pub struct Chars<'r, T> { priv buffer: &'r mut T } -impl<'r, T: Buffer> Iterator for Chars<'r, T> { - fn next(&mut self) -> Option { - self.buffer.read_char().ok() +impl<'r, T: Buffer> Iterator> for Chars<'r, T> { + fn next(&mut self) -> Option> { + match self.buffer.read_char() { + Ok(x) => Some(Ok(x)), + Err(IoError { kind: EndOfFile, ..}) => None, + Err(y) => Some(Err(y)) + } } } @@ -1095,9 +1099,8 @@ pub trait Buffer: Reader { /// /// # Error /// - /// This iterator will transform all error values to `None`, discarding the - /// cause of the error. If this is undesirable, it is recommended to call - /// `read_line` directly. + /// Any error other than `EndOfFile` that is produced by the underlying Reader + /// is returned by the iterator and should be handled by the caller. fn lines<'r>(&'r mut self) -> Lines<'r, Self> { Lines { buffer: self } } @@ -1183,9 +1186,8 @@ pub trait Buffer: Reader { /// /// # Error /// - /// This iterator will transform all error values to `None`, discarding the - /// cause of the error. If this is undesirable, it is recommended to call - /// `read_char` directly. + /// Any error other than `EndOfFile` that is produced by the underlying Reader + /// is returned by the iterator and should be handled by the caller. fn chars<'r>(&'r mut self) -> Chars<'r, Self> { Chars { buffer: self } } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 7188e119a8d63..d8bd0e6250f51 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -182,7 +182,7 @@ fn main() { let mut proc_mode = false; for line in rdr.lines() { - let line = line.trim().to_owned(); + let line = line.unwrap().trim().to_owned(); if line.len() == 0u { continue; } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index b77180e8e4ccf..d2ce61ee7556e 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -72,7 +72,7 @@ impl Sudoku { let mut g = vec::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] }); for line in reader.lines() { - let comps: ~[&str] = line.trim().split(',').collect(); + let comps: ~[&str] = line.unwrap().trim().split(',').collect(); if comps.len() == 3u { let row = from_str::(comps[0]).unwrap() as u8;