Skip to content

Commit c9f13b4

Browse files
committed
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
2 parents 3496e93 + 4c233d1 commit c9f13b4

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/libstd/io/mod.rs

+33
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,13 @@ pub trait Reader {
779779
self.read_byte().map(|i| i as i8)
780780
}
781781

782+
/// Creates a wrapper around a mutable reference to the reader.
783+
///
784+
/// This is useful to allow applying adaptors while still
785+
/// retaining ownership of the original value.
786+
fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
787+
RefReader { inner: self }
788+
}
782789
}
783790

784791
impl Reader for ~Reader {
@@ -789,6 +796,14 @@ impl<'a> Reader for &'a mut Reader {
789796
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
790797
}
791798

799+
pub struct RefReader<'a, R> {
800+
priv inner: &'a mut R
801+
}
802+
803+
impl<'a, R: Reader> Reader for RefReader<'a, R> {
804+
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
805+
}
806+
792807
fn extend_sign(val: u64, nbytes: uint) -> i64 {
793808
let shift = (8 - nbytes) * 8;
794809
(val << shift) as i64 >> shift
@@ -969,6 +984,14 @@ pub trait Writer {
969984
fn write_i8(&mut self, n: i8) -> IoResult<()> {
970985
self.write([n as u8])
971986
}
987+
988+
/// Creates a wrapper around a mutable reference to the writer.
989+
///
990+
/// This is useful to allow applying wrappers while still
991+
/// retaining ownership of the original value.
992+
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
993+
RefWriter { inner: self }
994+
}
972995
}
973996

974997
impl Writer for ~Writer {
@@ -981,6 +1004,16 @@ impl<'a> Writer for &'a mut Writer {
9811004
fn flush(&mut self) -> IoResult<()> { self.flush() }
9821005
}
9831006

1007+
pub struct RefWriter<'a, W> {
1008+
inner: &'a mut W
1009+
}
1010+
1011+
impl<'a, W: Writer> Writer for RefWriter<'a, W> {
1012+
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.inner.write(buf) }
1013+
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
1014+
}
1015+
1016+
9841017
pub trait Stream: Reader + Writer { }
9851018

9861019
impl<T: Reader + Writer> Stream for T {}

src/libstd/io/util.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@ use io;
1414
use vec::bytes::MutableByteVector;
1515

1616
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
17-
pub struct LimitReader<'a, R> {
17+
pub struct LimitReader<R> {
1818
priv limit: uint,
19-
priv inner: &'a mut R
19+
priv inner: R
2020
}
2121

22-
impl<'a, R: Reader> LimitReader<'a, R> {
22+
impl<R: Reader> LimitReader<R> {
2323
/// Creates a new `LimitReader`
24-
pub fn new<'a>(r: &'a mut R, limit: uint) -> LimitReader<'a, R> {
24+
pub fn new(r: R, limit: uint) -> LimitReader<R> {
2525
LimitReader { limit: limit, inner: r }
2626
}
27+
pub fn unwrap(self) -> R { self.inner }
2728
}
2829

29-
impl<'a, R: Reader> Reader for LimitReader<'a, R> {
30+
impl<R: Reader> Reader for LimitReader<R> {
3031
fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
3132
if self.limit == 0 {
3233
return Err(io::standard_error(io::EndOfFile));
@@ -192,7 +193,7 @@ mod test {
192193
fn test_bounded_reader_unlimited() {
193194
let mut r = MemReader::new(~[0, 1, 2]);
194195
{
195-
let mut r = LimitReader::new(&mut r, 4);
196+
let mut r = LimitReader::new(r.by_ref(), 4);
196197
assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
197198
}
198199
}
@@ -201,7 +202,7 @@ mod test {
201202
fn test_bound_reader_limited() {
202203
let mut r = MemReader::new(~[0, 1, 2]);
203204
{
204-
let mut r = LimitReader::new(&mut r, 2);
205+
let mut r = LimitReader::new(r.by_ref(), 2);
205206
assert_eq!(~[0, 1], r.read_to_end().unwrap());
206207
}
207208
assert_eq!(~[2], r.read_to_end().unwrap());

0 commit comments

Comments
 (0)