From d4dd4c68f82baf4d307012da1b4d6b91d26fb12f Mon Sep 17 00:00:00 2001
From: Palmer Cox
Date: Thu, 13 Feb 2014 23:27:53 -0500
Subject: [PATCH 1/2] Create RefReader and RefWriter adaptor structs
RefReader and RefWriter allow a caller to pass a Reader or Writer
instance by reference to generic functions that are expecting arguments
by value.
---
src/libstd/io/mod.rs | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 24b3d1cc4de70..c99fe587fc0d0 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 { 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 { 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 Stream for T {}
From 4c233d1c73edae4fb2609100528d3c952723453f Mon Sep 17 00:00:00 2001
From: Palmer Cox
Date: Thu, 13 Feb 2014 23:28:11 -0500
Subject: [PATCH 2/2] Update LimitReader to take the Reader to wrap by value
---
src/libstd/io/util.rs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index c4d92b36ecfa6..2e12fc0b9f290 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 {
priv limit: uint,
- priv inner: &'a mut R
+ priv inner: R
}
-impl<'a, R: Reader> LimitReader<'a, R> {
+impl LimitReader {
/// 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 {
LimitReader { limit: limit, inner: r }
}
+ pub fn unwrap(self) -> R { self.inner }
}
-impl<'a, R: Reader> Reader for LimitReader<'a, R> {
+impl Reader for LimitReader {
fn read(&mut self, buf: &mut [u8]) -> io::IoResult {
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());