diff --git a/src/buf/mod.rs b/src/buf/mod.rs index acc2888a872bae8e2bd415adccc7fcc2102895c7..e8d6faf54eb2f55e128044b94d71e0608590385d 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<Self> 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<Self> 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<Self> 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<Self> where Self: Sized { + Writer::new(self) + } } /* @@ -442,6 +463,43 @@ impl<'a> Sink for &'a mut Vec<u8> { * */ +/// Adapts a `Buf` to the `io::Read` trait +pub struct Reader<B> { + buf: B, +} + +impl<B: Buf> Reader<B> { + /// Return a `Reader` for the given `buf` + pub fn new(buf: B) -> Reader<B> { + 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<B: Buf + Sized> io::Read for Reader<B> { + fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> { + 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<B: MutBuf>(&mut self, buf: &mut B) -> io::Result<usize>; } @@ -461,6 +519,47 @@ impl<T: io::Read> ReadExt for T { } } +/// Adapts a `MutBuf` to the `io::Write` trait +pub struct Writer<B> { + buf: B, +} + +impl<B: MutBuf> Writer<B> { + /// Return a `Writer` for teh given `buf` + pub fn new(buf: B) -> Writer<B> { + 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<B: MutBuf + Sized> io::Write for Writer<B> { + fn write(&mut self, src: &[u8]) -> io::Result<usize> { + 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<B: Buf>(&mut self, buf: &mut B) -> io::Result<usize>; } diff --git a/src/lib.rs b/src/lib.rs index e31b763290344a78f74bacd0a7670a9487df7671..bb6741c46da395f51827a82a746f9f8fddb19b75 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};