about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2014-06-02 20:42:41 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2014-06-02 20:42:41 -0700
commit30a8bcbe3df484f7fa9f2523f429490c97af0382 (patch)
tree38bdf2e339610c42de781e07fc1ea21a68ca95cc /src/libstd
parent63e9b8f105ba0fe18e99cb280a23db82380960f4 (diff)
downloadrust-30a8bcbe3df484f7fa9f2523f429490c97af0382.tar.gz
rust-30a8bcbe3df484f7fa9f2523f429490c97af0382.zip
std: add `IterReader` to adapt iterators into readers
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/util.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 05d5f19eeff..59c42f111d0 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -229,6 +229,36 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
     }
 }
 
+/// A `Reader` which converts an `Iterator<u8>` into a `Reader`.
+pub struct IterReader<T> {
+    iter: T,
+}
+
+impl<T: Iterator<u8>> IterReader<T> {
+    /// Create a new `IterReader` which will read from the specified `Iterator`.
+    pub fn new(iter: T) -> IterReader<T> {
+        IterReader {
+            iter: iter,
+        }
+    }
+}
+
+impl<T: Iterator<u8>> Reader for IterReader<T> {
+    #[inline]
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
+        let mut len = 0;
+        for (slot, elt) in buf.mut_iter().zip(self.iter.by_ref()) {
+            *slot = elt;
+            len += 1;
+        }
+        if len == 0 {
+            Err(io::standard_error(io::EndOfFile))
+        } else {
+            Ok(len)
+        }
+    }
+}
+
 #[cfg(test)]
 mod test {
     use io::{MemReader, MemWriter, BufReader};
@@ -366,4 +396,23 @@ mod test {
             assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
         }
     }
+
+    #[test]
+    fn test_iter_reader() {
+        let mut r = IterReader::new(range(0u8, 8));
+        let mut buf = [0, 0, 0];
+        let len = r.read(buf).unwrap();
+        assert_eq!(len, 3);
+        assert!(buf == [0, 1, 2]);
+
+        let len = r.read(buf).unwrap();
+        assert_eq!(len, 3);
+        assert!(buf == [3, 4, 5]);
+
+        let len = r.read(buf).unwrap();
+        assert_eq!(len, 2);
+        assert!(buf == [6, 7, 5]);
+
+        assert_eq!(r.read(buf).unwrap_err().kind, io::EndOfFile);
+    }
 }