about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-02-09 11:57:26 -0800
committerbors <bors@rust-lang.org>2014-02-09 11:57:26 -0800
commit7985fbcb4dc88ff0a6b26c8ae81ba189bfa28fe7 (patch)
tree0653ebabf436ef0b5a606cb41361f2f3f265f12a
parent2780d9dd5410a5c093f27eacfb1684ddbfcb4632 (diff)
parent3a610e98a292f5bc75a720aa15c3600787a5ddb2 (diff)
downloadrust-7985fbcb4dc88ff0a6b26c8ae81ba189bfa28fe7.tar.gz
rust-7985fbcb4dc88ff0a6b26c8ae81ba189bfa28fe7.zip
auto merge of #12120 : gifnksm/rust/buffered-chars, r=alexcrichton
Add `std::io::Chars` iterator and `Buffer#chars()` method
-rw-r--r--src/libstd/io/buffered.rs10
-rw-r--r--src/libstd/io/mod.rs35
2 files changed, 45 insertions, 0 deletions
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 256f9d325f3..a48403f19a4 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -552,6 +552,16 @@ mod test {
         assert_eq!(reader.read_char(), Ok('ß'));
     }
 
+    #[test]
+    fn test_chars() {
+        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(), None);
+    }
+
     #[bench]
     fn bench_buffered_reader(bh: &mut Harness) {
         bh.iter(|| {
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 4d28143c75a..1c1df691a52 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1001,6 +1001,30 @@ impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> {
     }
 }
 
+/// An iterator that reads a utf8-encoded character on each iteration,
+/// until `.read_char()` returns `None`.
+///
+/// # Notes about the Iteration Protocol
+///
+/// The `Chars` may yield `None` and thus terminate
+/// an iteration, but continue to yield elements if iteration
+/// is attempted again.
+///
+/// # 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.
+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()
+    }
+}
+
 /// A Buffer is a type of reader which has some form of internal buffering to
 /// allow certain kinds of reading operations to be more optimized than others.
 /// This type extends the `Reader` trait with a few methods that are not
@@ -1146,6 +1170,17 @@ pub trait Buffer: Reader {
             None => Err(standard_error(InvalidInput))
         }
     }
+
+    /// Create an iterator that reads a utf8-encoded character on each iteration until EOF.
+    ///
+    /// # 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.
+    fn chars<'r>(&'r mut self) -> Chars<'r, Self> {
+        Chars { buffer: self }
+    }
 }
 
 pub enum SeekStyle {