From 83680dda27c1e5af4bd35cb71ea04c5e8e81f8af Mon Sep 17 00:00:00 2001
From: Carl Lerche <me@carllerche.com>
Date: Tue, 24 Mar 2015 22:10:29 -0700
Subject: [PATCH] Implement Source for std::io::Read

---
 src/lib.rs            | 23 ++++++++++++++---------
 test/test.rs          |  2 ++
 test/test_buf_fill.rs | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 9 deletions(-)
 create mode 100644 test/test_buf_fill.rs

diff --git a/src/lib.rs b/src/lib.rs
index adb35b8..5f1909e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -444,19 +444,24 @@ impl<'a> Source for &'a Bytes {
     }
 }
 
-impl<'a> Source for &'a mut (io::Read+'a) {
+impl<'a, R: io::Read+'a> Source for &'a mut R {
     type Error = io::Error;
 
-    fn fill<B: MutBuf>(self, _buf: &mut B) -> Result<usize, io::Error> {
-        unimplemented!();
-    }
-}
+    fn fill<B: MutBuf>(self, buf: &mut B) -> Result<usize, io::Error> {
+        let mut cnt = 0;
 
-impl<'a> Source for &'a mut (Iterator<Item=u8>+'a) {
-    type Error = BufError;
+        while buf.has_remaining() {
+            let i = try!(self.read(buf.mut_bytes()));
+
+            if i == 0 {
+                break;
+            }
+
+            buf.advance(i);
+            cnt += i;
+        }
 
-    fn fill<B: MutBuf>(self, _buf: &mut B) -> Result<usize, BufError> {
-        unimplemented!();
+        Ok(cnt)
     }
 }
 
diff --git a/test/test.rs b/test/test.rs
index 1e7670e..a497869 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -5,6 +5,8 @@ use rand::random;
 extern crate bytes;
 extern crate rand;
 
+mod test_buf;
+mod test_buf_fill;
 mod test_byte_buf;
 mod test_bytes;
 mod test_rope;
diff --git a/test/test_buf_fill.rs b/test/test_buf_fill.rs
new file mode 100644
index 0000000..515d75c
--- /dev/null
+++ b/test/test_buf_fill.rs
@@ -0,0 +1,43 @@
+use bytes::*;
+use std::io;
+
+#[test]
+pub fn test_filling_buf_from_reader() {
+    let mut reader = chunks(vec![b"foo", b"bar", b"baz"]);
+    let mut buf = ByteBuf::mut_with_capacity(1024);
+
+    assert_eq!(9, buf.write(&mut reader).unwrap());
+    assert_eq!(b"foobarbaz".to_bytes(), buf.flip().to_bytes());
+}
+
+fn chunks(chunks: Vec<&'static [u8]>) -> Chunked {
+    Chunked { chunks: chunks }
+}
+
+struct Chunked {
+    chunks: Vec<&'static [u8]>,
+}
+
+impl io::Read for Chunked {
+    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
+        use std::cmp;
+        use std::slice::bytes;
+
+        if self.chunks.is_empty() {
+            return Ok(0);
+        }
+
+        let src = self.chunks[0];
+        let len = cmp::min(src.len(), dst.len());
+
+        bytes::copy_memory(&mut dst[..len], &src[..len]);
+
+        if len < src.len() {
+            self.chunks[0] = &src[len..];
+        } else {
+            self.chunks.remove(0);
+        }
+
+        Ok(len)
+    }
+}
-- 
GitLab