summary refs log tree commit diff
path: root/src/libstd/io/mod.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-12 23:51:40 -0700
committerbors <bors@rust-lang.org>2014-03-12 23:51:40 -0700
commit6cbba7c54e4e1e02d4ff3ffacf46d15d0f3a039c (patch)
treeeb357b706573d3bb19a23fc7c12969cb7140373c /src/libstd/io/mod.rs
parent792da8424f4f422c2750607dcc243315fdff9fc3 (diff)
parent9ba6bb5a71adeb861f8bf21c2b1f2fde3132480d (diff)
downloadrust-6cbba7c54e4e1e02d4ff3ffacf46d15d0f3a039c.tar.gz
rust-6cbba7c54e4e1e02d4ff3ffacf46d15d0f3a039c.zip
auto merge of #12414 : DaGenix/rust/failing-iterator-wrappers, r=alexcrichton
 
Most IO related functions return an IoResult so that the caller can handle failure in whatever way is appropriate. However, the `lines`, `bytes`, and `chars` iterators all supress errors. This means that code that needs to handle errors can't use any of these iterators. All three of these iterators were updated to produce IoResults.
    
Fixes #12368

Diffstat (limited to 'src/libstd/io/mod.rs')
-rw-r--r--src/libstd/io/mod.rs60
1 files changed, 31 insertions, 29 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index c6795fad1a5..3aaee59288f 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<T: Reader + Writer> 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<T: Reader + Writer> 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<IoResult<~str>> for Lines<'r, T> {
+    fn next(&mut self) -> Option<IoResult<~str>> {
+        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<char> for Chars<'r, T> {
-    fn next(&mut self) -> Option<char> {
-        self.buffer.read_char().ok()
+impl<'r, T: Buffer> Iterator<IoResult<char>> for Chars<'r, T> {
+    fn next(&mut self) -> Option<IoResult<char>> {
+        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 }
     }