mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-18 00:00:12 +02:00
Move "extra" methods to extension traits (#306)
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
use crate::{Buf, BufMut};
|
||||
use crate::buf::IntoIter;
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::{IoSlice};
|
||||
#[cfg(feature = "std")]
|
||||
use crate::buf::IoSliceMut;
|
||||
|
||||
/// A `Chain` sequences two buffers.
|
||||
///
|
||||
/// `Chain` is an adapter that links two underlying buffers and provides a
|
||||
/// continuous view across both buffers. It is able to sequence either immutable
|
||||
/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values).
|
||||
///
|
||||
/// This struct is generally created by calling [`Buf::chain`]. Please see that
|
||||
/// function's documentation for more detail.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Bytes, Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = (&b"hello "[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// let full: Bytes = buf.to_bytes();
|
||||
/// assert_eq!(full[..], b"hello world"[..]);
|
||||
/// ```
|
||||
///
|
||||
/// [`Buf::chain`]: trait.Buf.html#method.chain
|
||||
/// [`Buf`]: trait.Buf.html
|
||||
/// [`BufMut`]: trait.BufMut.html
|
||||
#[derive(Debug)]
|
||||
pub struct Chain<T, U> {
|
||||
a: T,
|
||||
b: U,
|
||||
}
|
||||
|
||||
impl<T, U> Chain<T, U> {
|
||||
/// Creates a new `Chain` sequencing the provided values.
|
||||
pub fn new(a: T, b: U) -> Chain<T, U> {
|
||||
Chain {
|
||||
a,
|
||||
b,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a reference to the first underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf.first_ref()[..], b"hello"[..]);
|
||||
/// ```
|
||||
pub fn first_ref(&self) -> &T {
|
||||
&self.a
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the first underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// buf.first_mut().advance(1);
|
||||
///
|
||||
/// let full = buf.to_bytes();
|
||||
/// assert_eq!(full, b"elloworld"[..]);
|
||||
/// ```
|
||||
pub fn first_mut(&mut self) -> &mut T {
|
||||
&mut self.a
|
||||
}
|
||||
|
||||
/// Gets a reference to the last underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let buf = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// assert_eq!(buf.last_ref()[..], b"world"[..]);
|
||||
/// ```
|
||||
pub fn last_ref(&self) -> &U {
|
||||
&self.b
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the last underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = (&b"hello "[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// buf.last_mut().advance(1);
|
||||
///
|
||||
/// let full = buf.to_bytes();
|
||||
/// assert_eq!(full, b"hello orld"[..]);
|
||||
/// ```
|
||||
pub fn last_mut(&mut self) -> &mut U {
|
||||
&mut self.b
|
||||
}
|
||||
|
||||
/// Consumes this `Chain`, returning the underlying values.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let chain = (&b"hello"[..])
|
||||
/// .chain(&b"world"[..]);
|
||||
///
|
||||
/// let (first, last) = chain.into_inner();
|
||||
/// assert_eq!(first[..], b"hello"[..]);
|
||||
/// assert_eq!(last[..], b"world"[..]);
|
||||
/// ```
|
||||
pub fn into_inner(self) -> (T, U) {
|
||||
(self.a, self.b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Buf for Chain<T, U>
|
||||
where T: Buf,
|
||||
U: Buf,
|
||||
{
|
||||
fn remaining(&self) -> usize {
|
||||
self.a.remaining() + self.b.remaining()
|
||||
}
|
||||
|
||||
fn bytes(&self) -> &[u8] {
|
||||
if self.a.has_remaining() {
|
||||
self.a.bytes()
|
||||
} else {
|
||||
self.b.bytes()
|
||||
}
|
||||
}
|
||||
|
||||
fn advance(&mut self, mut cnt: usize) {
|
||||
let a_rem = self.a.remaining();
|
||||
|
||||
if a_rem != 0 {
|
||||
if a_rem >= cnt {
|
||||
self.a.advance(cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Consume what is left of a
|
||||
self.a.advance(a_rem);
|
||||
|
||||
cnt -= a_rem;
|
||||
}
|
||||
|
||||
self.b.advance(cnt);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
|
||||
let mut n = self.a.bytes_vectored(dst);
|
||||
n += self.b.bytes_vectored(&mut dst[n..]);
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> BufMut for Chain<T, U>
|
||||
where T: BufMut,
|
||||
U: BufMut,
|
||||
{
|
||||
fn remaining_mut(&self) -> usize {
|
||||
self.a.remaining_mut() + self.b.remaining_mut()
|
||||
}
|
||||
|
||||
fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
if self.a.has_remaining_mut() {
|
||||
self.a.bytes_mut()
|
||||
} else {
|
||||
self.b.bytes_mut()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn advance_mut(&mut self, mut cnt: usize) {
|
||||
let a_rem = self.a.remaining_mut();
|
||||
|
||||
if a_rem != 0 {
|
||||
if a_rem >= cnt {
|
||||
self.a.advance_mut(cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Consume what is left of a
|
||||
self.a.advance_mut(a_rem);
|
||||
|
||||
cnt -= a_rem;
|
||||
}
|
||||
|
||||
self.b.advance_mut(cnt);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
|
||||
let mut n = self.a.bytes_vectored_mut(dst);
|
||||
n += self.b.bytes_vectored_mut(&mut dst[n..]);
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> IntoIterator for Chain<T, U>
|
||||
where
|
||||
T: Buf,
|
||||
U: Buf,
|
||||
{
|
||||
type Item = u8;
|
||||
type IntoIter = IntoIter<Chain<T, U>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter::new(self)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
//! Extra utilities for `Buf` and `BufMut` types.
|
||||
|
||||
use super::{Buf, BufMut};
|
||||
|
||||
mod chain;
|
||||
#[cfg(feature = "std")]
|
||||
mod reader;
|
||||
mod take;
|
||||
#[cfg(feature = "std")]
|
||||
mod writer;
|
||||
|
||||
use self::take::Take;
|
||||
use self::chain::Chain;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use self::{reader::Reader, writer::Writer};
|
||||
|
||||
/// Extra methods for implementations of `Buf`.
|
||||
pub trait BufExt: Buf {
|
||||
/// Creates an adaptor which will read at most `limit` bytes from `self`.
|
||||
///
|
||||
/// This function returns a new instance of `Buf` which will read at most
|
||||
/// `limit` bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world"[..].take(5);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(dst, b"hello");
|
||||
///
|
||||
/// let mut buf = buf.into_inner();
|
||||
/// dst.clear();
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(dst, b" world");
|
||||
/// ```
|
||||
fn take(self, limit: usize) -> Take<Self>
|
||||
where Self: Sized
|
||||
{
|
||||
take::new(self, limit)
|
||||
}
|
||||
|
||||
/// Creates an adaptor which will chain this buffer with another.
|
||||
///
|
||||
/// The returned `Buf` instance will first consume all bytes from `self`.
|
||||
/// Afterwards the output is equivalent to the output of next.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut chain = b"hello "[..].chain(&b"world"[..]);
|
||||
///
|
||||
/// let full = chain.to_bytes();
|
||||
/// assert_eq!(full.bytes(), b"hello world");
|
||||
/// ```
|
||||
fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
|
||||
where Self: Sized
|
||||
{
|
||||
Chain::new(self, next)
|
||||
}
|
||||
|
||||
/// Creates an adaptor which implements the `Read` trait for `self`.
|
||||
///
|
||||
/// This function returns a new value which implements `Read` by adapting
|
||||
/// the `Read` trait functions to the `Buf` trait functions. Given that
|
||||
/// `Buf` operations are infallible, none of the `Read` functions will
|
||||
/// return with `Err`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{Buf, Bytes, buf::BufExt};
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// let buf = Bytes::from("hello world");
|
||||
///
|
||||
/// let mut reader = buf.reader();
|
||||
/// let mut dst = [0; 1024];
|
||||
///
|
||||
/// let num = reader.read(&mut dst).unwrap();
|
||||
///
|
||||
/// assert_eq!(11, num);
|
||||
/// assert_eq!(&dst[..11], &b"hello world"[..]);
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
fn reader(self) -> Reader<Self> where Self: Sized {
|
||||
reader::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Buf + ?Sized> BufExt for B {}
|
||||
|
||||
/// Extra methods for implementations of `BufMut`.
|
||||
pub trait BufMutExt: BufMut {
|
||||
/// Creates an adaptor which implements the `Write` trait for `self`.
|
||||
///
|
||||
/// This function returns a new value which implements `Write` by adapting
|
||||
/// the `Write` trait functions to the `BufMut` trait functions. Given that
|
||||
/// `BufMut` operations are infallible, none of the `Write` functions will
|
||||
/// return with `Err`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bytes::{BufMut, buf::BufMutExt};
|
||||
/// use std::io::Write;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
///
|
||||
/// let num = buf.write(&b"hello world"[..]).unwrap();
|
||||
/// assert_eq!(11, num);
|
||||
///
|
||||
/// let buf = buf.into_inner();
|
||||
///
|
||||
/// assert_eq!(*buf, b"hello world"[..]);
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
fn writer(self) -> Writer<Self> where Self: Sized {
|
||||
writer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BufMut + ?Sized> BufMutExt for B {}
|
||||
@@ -0,0 +1,81 @@
|
||||
use crate::{Buf};
|
||||
|
||||
use std::{cmp, io};
|
||||
|
||||
/// A `Buf` adapter which implements `io::Read` for the inner value.
|
||||
///
|
||||
/// This struct is generally created by calling `reader()` on `Buf`. See
|
||||
/// documentation of [`reader()`](trait.Buf.html#method.reader) for more
|
||||
/// details.
|
||||
#[derive(Debug)]
|
||||
pub struct Reader<B> {
|
||||
buf: B,
|
||||
}
|
||||
|
||||
pub fn new<B>(buf: B) -> Reader<B> {
|
||||
Reader { buf }
|
||||
}
|
||||
|
||||
impl<B: Buf> Reader<B> {
|
||||
/// Gets a reference to the underlying `Buf`.
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::buf::BufExt;
|
||||
///
|
||||
/// let mut buf = b"hello world".reader();
|
||||
///
|
||||
/// assert_eq!(b"hello world", buf.get_ref());
|
||||
/// ```
|
||||
pub fn get_ref(&self) -> &B {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying `Buf`.
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying `Buf`.
|
||||
pub fn get_mut(&mut self) -> &mut B {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
/// Consumes this `Reader`, returning the underlying value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
/// use std::io;
|
||||
///
|
||||
/// let mut buf = b"hello world".reader();
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// io::copy(&mut buf, &mut dst).unwrap();
|
||||
///
|
||||
/// let buf = buf.into_inner();
|
||||
/// assert_eq!(0, buf.remaining());
|
||||
/// ```
|
||||
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_slice(&mut self.buf, &mut dst[0..len]);
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Buf + Sized> io::BufRead for Reader<B> {
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
||||
Ok(self.buf.bytes())
|
||||
}
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.buf.advance(amt)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
use crate::Buf;
|
||||
|
||||
use core::cmp;
|
||||
|
||||
/// A `Buf` adapter which limits the bytes read from an underlying buffer.
|
||||
///
|
||||
/// This struct is generally created by calling `take()` on `Buf`. See
|
||||
/// documentation of [`take()`](trait.Buf.html#method.take) for more details.
|
||||
#[derive(Debug)]
|
||||
pub struct Take<T> {
|
||||
inner: T,
|
||||
limit: usize,
|
||||
}
|
||||
|
||||
pub fn new<T>(inner: T, limit: usize) -> Take<T> {
|
||||
Take {
|
||||
inner,
|
||||
limit,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Take<T> {
|
||||
/// Consumes this `Take`, returning the underlying value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::buf::{Buf, BufMut, BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"he"[..]);
|
||||
///
|
||||
/// let mut buf = buf.into_inner();
|
||||
///
|
||||
/// dst.clear();
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"llo world"[..]);
|
||||
/// ```
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
|
||||
/// Gets a reference to the underlying `Buf`.
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
///
|
||||
/// assert_eq!(11, buf.get_ref().remaining());
|
||||
/// ```
|
||||
pub fn get_ref(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying `Buf`.
|
||||
///
|
||||
/// It is inadvisable to directly read from the underlying `Buf`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// buf.get_mut().advance(2);
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"ll"[..]);
|
||||
/// ```
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Returns the maximum number of bytes that can be read.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// If the inner `Buf` has fewer bytes than indicated by this method then
|
||||
/// that is the actual number of available bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
///
|
||||
/// assert_eq!(2, buf.limit());
|
||||
/// assert_eq!(b'h', buf.get_u8());
|
||||
/// assert_eq!(1, buf.limit());
|
||||
/// ```
|
||||
pub fn limit(&self) -> usize {
|
||||
self.limit
|
||||
}
|
||||
|
||||
/// Sets the maximum number of bytes that can be read.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// If the inner `Buf` has fewer bytes than `lim` then that is the actual
|
||||
/// number of available bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::{Buf, BufMut, buf::BufExt};
|
||||
///
|
||||
/// let mut buf = b"hello world".take(2);
|
||||
/// let mut dst = vec![];
|
||||
///
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"he"[..]);
|
||||
///
|
||||
/// dst.clear();
|
||||
///
|
||||
/// buf.set_limit(3);
|
||||
/// dst.put(&mut buf);
|
||||
/// assert_eq!(*dst, b"llo"[..]);
|
||||
/// ```
|
||||
pub fn set_limit(&mut self, lim: usize) {
|
||||
self.limit = lim
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Buf> Buf for Take<T> {
|
||||
fn remaining(&self) -> usize {
|
||||
cmp::min(self.inner.remaining(), self.limit)
|
||||
}
|
||||
|
||||
fn bytes(&self) -> &[u8] {
|
||||
let bytes = self.inner.bytes();
|
||||
&bytes[..cmp::min(bytes.len(), self.limit)]
|
||||
}
|
||||
|
||||
fn advance(&mut self, cnt: usize) {
|
||||
assert!(cnt <= self.limit);
|
||||
self.inner.advance(cnt);
|
||||
self.limit -= cnt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
use crate::BufMut;
|
||||
|
||||
use std::{cmp, io};
|
||||
|
||||
/// A `BufMut` adapter which implements `io::Write` for the inner value.
|
||||
///
|
||||
/// This struct is generally created by calling `writer()` on `BufMut`. See
|
||||
/// documentation of [`writer()`](trait.BufMut.html#method.writer) for more
|
||||
/// details.
|
||||
#[derive(Debug)]
|
||||
pub struct Writer<B> {
|
||||
buf: B,
|
||||
}
|
||||
|
||||
pub fn new<B>(buf: B) -> Writer<B> {
|
||||
Writer { buf }
|
||||
}
|
||||
|
||||
impl<B: BufMut> Writer<B> {
|
||||
/// Gets a reference to the underlying `BufMut`.
|
||||
///
|
||||
/// It is inadvisable to directly write to the underlying `BufMut`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::buf::BufMutExt;
|
||||
///
|
||||
/// let mut buf = Vec::with_capacity(1024).writer();
|
||||
///
|
||||
/// assert_eq!(1024, buf.get_ref().capacity());
|
||||
/// ```
|
||||
pub fn get_ref(&self) -> &B {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the underlying `BufMut`.
|
||||
///
|
||||
/// It is inadvisable to directly write to the underlying `BufMut`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::buf::BufMutExt;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
///
|
||||
/// buf.get_mut().reserve(1024);
|
||||
///
|
||||
/// assert_eq!(1024, buf.get_ref().capacity());
|
||||
/// ```
|
||||
pub fn get_mut(&mut self) -> &mut B {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
/// Consumes this `Writer`, returning the underlying value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use bytes::buf::BufMutExt;
|
||||
/// use std::io;
|
||||
///
|
||||
/// let mut buf = vec![].writer();
|
||||
/// let mut src = &b"hello world"[..];
|
||||
///
|
||||
/// io::copy(&mut src, &mut buf).unwrap();
|
||||
///
|
||||
/// let buf = buf.into_inner();
|
||||
/// assert_eq!(*buf, b"hello world"[..]);
|
||||
/// ```
|
||||
pub fn into_inner(self) -> B {
|
||||
self.buf
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BufMut + Sized> io::Write for Writer<B> {
|
||||
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
|
||||
let n = cmp::min(self.buf.remaining_mut(), src.len());
|
||||
|
||||
self.buf.put(&src[0..n]);
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user