diff --git a/src/buf/mod.rs b/src/buf/mod.rs index acc2888..e8d6faf 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -166,10 +166,20 @@ pub trait Buf { T::read_f64(&buf) } + /// Creates a "by reference" adaptor for this instance of Buf + fn by_ref(&mut self) -> &mut Self where Self: Sized { + self + } + /// Create an adapter which will limit at most `limit` bytes from it. fn take(self, limit: usize) -> Take where Self: Sized { Take::new(self, limit) } + + /// Return a `Reader` for the value. Allows using a `Buf` as an `io::Read` + fn reader(self) -> Reader where Self: Sized { + Reader::new(self) + } } /// A trait for values that provide sequential write access to bytes. @@ -335,10 +345,21 @@ pub trait MutBuf { self.write_slice(&buf) } + /// Creates a "by reference" adaptor for this instance of MutBuf + fn by_ref(&mut self) -> &mut Self where Self: Sized { + self + } + /// Create an adapter which will limit at most `limit` bytes from it. fn take(self, limit: usize) -> Take where Self: Sized { Take::new(self, limit) } + + /// Return a `Write` for the value. Allows using a `MutBuf` as an + /// `io::Write` + fn writer(self) -> Writer where Self: Sized { + Writer::new(self) + } } /* @@ -442,6 +463,43 @@ impl<'a> Sink for &'a mut Vec { * */ +/// Adapts a `Buf` to the `io::Read` trait +pub struct Reader { + buf: B, +} + +impl Reader { + /// Return a `Reader` for the given `buf` + pub fn new(buf: B) -> Reader { + Reader { buf: buf } + } + + /// Gets a reference to the underlying buf. + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying buf. + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Unwraps this `Reader`, returning the underlying `Buf` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl io::Read for Reader { + fn read(&mut self, dst: &mut [u8]) -> io::Result { + let len = cmp::min(self.buf.remaining(), dst.len()); + + Buf::copy_to(&mut self.buf, &mut dst[0..len]); + Ok(len) + } +} + +/// Buffer related extension for `io::Read` pub trait ReadExt { fn read_buf(&mut self, buf: &mut B) -> io::Result; } @@ -461,6 +519,47 @@ impl ReadExt for T { } } +/// Adapts a `MutBuf` to the `io::Write` trait +pub struct Writer { + buf: B, +} + +impl Writer { + /// Return a `Writer` for teh given `buf` + pub fn new(buf: B) -> Writer { + Writer { buf: buf } + } + + /// Gets a reference to the underlying buf. + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying buf. + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Unwraps this `Writer`, returning the underlying `MutBuf` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl io::Write for Writer { + fn write(&mut self, src: &[u8]) -> io::Result { + let n = cmp::min(self.buf.remaining(), src.len()); + + self.buf.copy_from(&src[0..n]); + Ok(n) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +/// Buffer related extension for `io::Write` pub trait WriteExt { fn write_buf(&mut self, buf: &mut B) -> io::Result; } diff --git a/src/lib.rs b/src/lib.rs index e31b763..bb6741c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ mod bytes; pub mod alloc; -pub use buf::{Buf, MutBuf, Source, Sink, ReadExt, WriteExt, Fmt}; +pub use buf::{Buf, MutBuf, Source, Sink, Reader, ReadExt, Writer, WriteExt, Fmt}; pub use buf::append::AppendBuf; pub use buf::block::{BlockBuf, BlockBufCursor}; pub use buf::byte::{ByteBuf, MutByteBuf};