about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-02-14 23:46:29 -0800
committerbors <bors@rust-lang.org>2014-02-14 23:46:29 -0800
commitc9f13b47febb81ef339a15adf0f6ad7a2265c46d (patch)
treee8f17e3a7706075264090d1af31d1f8a741c2a4d
parent3496e93d13590140242f862c905dc2d591d2e2ea (diff)
parent4c233d1c73edae4fb2609100528d3c952723453f (diff)
downloadrust-c9f13b47febb81ef339a15adf0f6ad7a2265c46d.tar.gz
rust-c9f13b47febb81ef339a15adf0f6ad7a2265c46d.zip
auto merge of #12230 : DaGenix/rust/io-decorator-changes, r=sfackler
I created RefReader and RefWriter structs that wrap a mutable reference to a Reader or Writer value. This works exactly like the ByRef struct in the iter module and allows passing a reference to a Reader or Writer to function expecting a Reader or Writer by value with the caller retaining ownership to the original value.

I also modified LimitReader to take the wrapped Reader by value instead of by reference.

@sfackler
-rw-r--r--src/libstd/io/mod.rs33
-rw-r--r--src/libstd/io/util.rs15
2 files changed, 41 insertions, 7 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 24b3d1cc4de..c99fe587fc0 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -779,6 +779,13 @@ pub trait Reader {
         self.read_byte().map(|i| i as i8)
     }
 
+    /// Creates a wrapper around a mutable reference to the reader.
+    ///
+    /// This is useful to allow applying adaptors while still
+    /// retaining ownership of the original value.
+    fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
+        RefReader { inner: self }
+    }
 }
 
 impl Reader for ~Reader {
@@ -789,6 +796,14 @@ impl<'a> Reader for &'a mut Reader {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
 }
 
+pub struct RefReader<'a, R> {
+    priv inner: &'a mut R
+}
+
+impl<'a, R: Reader> Reader for RefReader<'a, R> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
+}
+
 fn extend_sign(val: u64, nbytes: uint) -> i64 {
     let shift = (8 - nbytes) * 8;
     (val << shift) as i64 >> shift
@@ -969,6 +984,14 @@ pub trait Writer {
     fn write_i8(&mut self, n: i8) -> IoResult<()> {
         self.write([n as u8])
     }
+
+    /// Creates a wrapper around a mutable reference to the writer.
+    ///
+    /// This is useful to allow applying wrappers while still
+    /// retaining ownership of the original value.
+    fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
+        RefWriter { inner: self }
+    }
 }
 
 impl Writer for ~Writer {
@@ -981,6 +1004,16 @@ impl<'a> Writer for &'a mut Writer {
     fn flush(&mut self) -> IoResult<()> { self.flush() }
 }
 
+pub struct RefWriter<'a, W> {
+    inner: &'a mut W
+}
+
+impl<'a, W: Writer> Writer for RefWriter<'a, W> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
+    fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
+}
+
+
 pub trait Stream: Reader + Writer { }
 
 impl<T: Reader + Writer> Stream for T {}
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index c4d92b36ecf..2e12fc0b9f2 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -14,19 +14,20 @@ use io;
 use vec::bytes::MutableByteVector;
 
 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
-pub struct LimitReader<'a, R> {
+pub struct LimitReader<R> {
     priv limit: uint,
-    priv inner: &'a mut R
+    priv inner: R
 }
 
-impl<'a, R: Reader> LimitReader<'a, R> {
+impl<R: Reader> LimitReader<R> {
     /// Creates a new `LimitReader`
-    pub fn new<'a>(r: &'a mut R, limit: uint) -> LimitReader<'a, R> {
+    pub fn new(r: R, limit: uint) -> LimitReader<R> {
         LimitReader { limit: limit, inner: r }
     }
+    pub fn unwrap(self) -> R { self.inner }
 }
 
-impl<'a, R: Reader> Reader for LimitReader<'a, R> {
+impl<R: Reader> Reader for LimitReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
         if self.limit == 0 {
             return Err(io::standard_error(io::EndOfFile));
@@ -192,7 +193,7 @@ mod test {
     fn test_bounded_reader_unlimited() {
         let mut r = MemReader::new(~[0, 1, 2]);
         {
-            let mut r = LimitReader::new(&mut r, 4);
+            let mut r = LimitReader::new(r.by_ref(), 4);
             assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
         }
     }
@@ -201,7 +202,7 @@ mod test {
     fn test_bound_reader_limited() {
         let mut r = MemReader::new(~[0, 1, 2]);
         {
-            let mut r = LimitReader::new(&mut r, 2);
+            let mut r = LimitReader::new(r.by_ref(), 2);
             assert_eq!(~[0, 1], r.read_to_end().unwrap());
         }
         assert_eq!(~[2], r.read_to_end().unwrap());