diff --git a/examples/into_buf.rs b/examples/into_buf.rs new file mode 100644 index 0000000000000000000000000000000000000000..753a5ad8a603829f14752109746d361104258981 --- /dev/null +++ b/examples/into_buf.rs @@ -0,0 +1,17 @@ +extern crate bytes; + +use bytes::{Buf, IntoBuf, Bytes}; + +pub fn dump<T>(data: &T) where + for<'a> &'a T: IntoBuf, +{ + let mut dst: Vec<u8> = vec![]; + data.into_buf().copy_to(&mut dst); + println!("GOT: {:?}", dst); +} + +pub fn main() { + let b = Bytes::from_slice(b"hello world"); + dump(&b); + dump(&b); +} diff --git a/src/imp/buf/mod.rs b/src/imp/buf/mod.rs index ca41f616d572d3eb44b2908c001c9d9ea1398024..f6b700409362d2f285d99411e3dd539087685231 100644 --- a/src/imp/buf/mod.rs +++ b/src/imp/buf/mod.rs @@ -363,6 +363,40 @@ pub trait MutBuf { } } +/* + * + * ===== IntoBuf ===== + * + */ + +/// Conversion into a `Buf` +/// +/// Usually, `IntoBuf` is implemented on references of types and not directly +/// on the types themselves. For example, `IntoBuf` is implemented for `&'a +/// Vec<u8>` and not `Vec<u8>` directly. +pub trait IntoBuf { + type Buf: Buf; + + fn into_buf(self) -> Self::Buf; +} + +impl<'a> IntoBuf for &'a [u8] { + type Buf = io::Cursor<&'a [u8]>; + + /// Creates a buffer from a value + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a Vec<u8> { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(&self[..]) + } +} + /* * * ===== Sink / Source ===== diff --git a/src/imp/bytes/mod.rs b/src/imp/bytes/mod.rs index 21f51aff17f06f03c1fb1234ceffa37591c10d6f..daf4bd47e3a2de88410ccd814612ffa69f501ef8 100644 --- a/src/imp/bytes/mod.rs +++ b/src/imp/bytes/mod.rs @@ -2,7 +2,7 @@ pub mod rope; pub mod seq; pub mod small; -use Buf; +use {Buf, IntoBuf}; use self::seq::Seq; use self::small::Small; use self::rope::{Rope, RopeBuf}; @@ -188,6 +188,20 @@ impl cmp::PartialEq<Bytes> for Bytes { } } +impl<'a> IntoBuf for &'a Bytes { + type Buf = BytesBuf<'a>; + + fn into_buf(self) -> Self::Buf { + self.buf() + } +} + +/* + * + * ===== BytesBuf ===== + * + */ + impl<'a> Buf for BytesBuf<'a> { fn remaining(&self) -> usize { match self.kind { diff --git a/src/lib.rs b/src/lib.rs index a3c92bad6e821859b5b3d6e58af2111bd6f86198..6b51d4586fa59ca7d286dac0ec9a1d541f577bd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ mod imp; // TODO: delete mod alloc; -pub use imp::buf::{Buf, MutBuf}; +pub use imp::buf::{Buf, MutBuf, IntoBuf}; pub use imp::bytes::Bytes; pub mod buf {