mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-24 00:00:14 +02:00
Polish API surface
This commit is contained in:
+51
-48
@@ -2,9 +2,30 @@ use {Bytes};
|
|||||||
use byteorder::ByteOrder;
|
use byteorder::ByteOrder;
|
||||||
use std::{cmp, io, ptr, usize};
|
use std::{cmp, io, ptr, usize};
|
||||||
|
|
||||||
/// A trait for values that provide sequential read access to bytes.
|
/// Read bytes from a buffer.
|
||||||
|
///
|
||||||
|
/// A buffer stores bytes in memory such that read access is infallible. The
|
||||||
|
/// underlying storage may or may not be in contiguous memory. A `Buf` value is
|
||||||
|
/// a cursor into the buffer. Reading from `Buf` advances the cursor position.
|
||||||
|
///
|
||||||
|
/// The simplest `Buf` is a `Cursor` wrapping a `[u8]`.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use bytes::Buf;
|
||||||
|
/// use std::io::Cursor;
|
||||||
|
///
|
||||||
|
/// let mut buf = Cursor::new(b"hello world");
|
||||||
|
///
|
||||||
|
/// assert_eq!(b'h', buf.get_u8());
|
||||||
|
/// assert_eq!(b'e', buf.get_u8());
|
||||||
|
/// assert_eq!(b'l', buf.get_u8());
|
||||||
|
///
|
||||||
|
/// let mut rest = vec![];
|
||||||
|
/// buf.copy_to(&mut rest);
|
||||||
|
///
|
||||||
|
/// assert_eq!(&rest[..], b"lo world");
|
||||||
|
/// ```
|
||||||
pub trait Buf {
|
pub trait Buf {
|
||||||
|
|
||||||
/// Returns the number of bytes that can be accessed from the Buf
|
/// Returns the number of bytes that can be accessed from the Buf
|
||||||
fn remaining(&self) -> usize;
|
fn remaining(&self) -> usize;
|
||||||
|
|
||||||
@@ -70,16 +91,6 @@ pub trait Buf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets an unsigned 8 bit integer from the `Buf` without advancing the
|
|
||||||
/// buffer cursor
|
|
||||||
fn peek_u8(&self) -> Option<u8> {
|
|
||||||
if self.has_remaining() {
|
|
||||||
Some(self.bytes()[0])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets an unsigned 8 bit integer from the `Buf`.
|
/// Gets an unsigned 8 bit integer from the `Buf`.
|
||||||
fn get_u8(&mut self) -> u8 {
|
fn get_u8(&mut self) -> u8 {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
@@ -203,7 +214,7 @@ pub trait BufMut {
|
|||||||
///
|
///
|
||||||
/// Panics if `self` does not have enough capacity to copy all the data
|
/// Panics if `self` does not have enough capacity to copy all the data
|
||||||
/// from `src`
|
/// from `src`
|
||||||
fn copy_from<S: Source>(&mut self, src: S) where Self: Sized {
|
fn put<S: Source>(&mut self, src: S) where Self: Sized {
|
||||||
src.source(self);
|
src.source(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,14 +230,14 @@ pub trait BufMut {
|
|||||||
///
|
///
|
||||||
/// {
|
/// {
|
||||||
/// let mut buf = Cursor::new(&mut dst);
|
/// let mut buf = Cursor::new(&mut dst);
|
||||||
/// buf.copy_from_slice(b"hello");
|
/// buf.put_slice(b"hello");
|
||||||
///
|
///
|
||||||
/// assert_eq!(1, buf.remaining_mut());
|
/// assert_eq!(1, buf.remaining_mut());
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// assert_eq!(b"hello\0", &dst);
|
/// assert_eq!(b"hello\0", &dst);
|
||||||
/// ```
|
/// ```
|
||||||
fn copy_from_slice(&mut self, src: &[u8]) {
|
fn put_slice(&mut self, src: &[u8]) {
|
||||||
let mut off = 0;
|
let mut off = 0;
|
||||||
|
|
||||||
assert!(self.remaining_mut() >= src.len(), "buffer overflow");
|
assert!(self.remaining_mut() >= src.len(), "buffer overflow");
|
||||||
@@ -251,66 +262,46 @@ pub trait BufMut {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the given string into self.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// The function panics if `self` does not have enough remaining capacity
|
|
||||||
/// to write the full string.
|
|
||||||
fn put_str(&mut self, src: &str) {
|
|
||||||
self.copy_from_slice(src.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned 8 bit integer to the BufMut.
|
|
||||||
fn put_u8(&mut self, n: u8) {
|
|
||||||
self.copy_from_slice(&[n])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 8 bit integer to the BufMut.
|
|
||||||
fn put_i8(&mut self, n: i8) {
|
|
||||||
self.copy_from_slice(&[n as u8])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned 16 bit integer to the BufMut.
|
/// Writes an unsigned 16 bit integer to the BufMut.
|
||||||
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
|
fn put_u16<T: ByteOrder>(&mut self, n: u16) {
|
||||||
let mut buf = [0; 2];
|
let mut buf = [0; 2];
|
||||||
T::write_u16(&mut buf, n);
|
T::write_u16(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a signed 16 bit integer to the BufMut.
|
/// Writes a signed 16 bit integer to the BufMut.
|
||||||
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
|
fn put_i16<T: ByteOrder>(&mut self, n: i16) {
|
||||||
let mut buf = [0; 2];
|
let mut buf = [0; 2];
|
||||||
T::write_i16(&mut buf, n);
|
T::write_i16(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes an unsigned 32 bit integer to the BufMut.
|
/// Writes an unsigned 32 bit integer to the BufMut.
|
||||||
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
|
fn put_u32<T: ByteOrder>(&mut self, n: u32) {
|
||||||
let mut buf = [0; 4];
|
let mut buf = [0; 4];
|
||||||
T::write_u32(&mut buf, n);
|
T::write_u32(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a signed 32 bit integer to the BufMut.
|
/// Writes a signed 32 bit integer to the BufMut.
|
||||||
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
|
fn put_i32<T: ByteOrder>(&mut self, n: i32) {
|
||||||
let mut buf = [0; 4];
|
let mut buf = [0; 4];
|
||||||
T::write_i32(&mut buf, n);
|
T::write_i32(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes an unsigned 64 bit integer to the BufMut.
|
/// Writes an unsigned 64 bit integer to the BufMut.
|
||||||
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
|
fn put_u64<T: ByteOrder>(&mut self, n: u64) {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
T::write_u64(&mut buf, n);
|
T::write_u64(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a signed 64 bit integer to the BufMut.
|
/// Writes a signed 64 bit integer to the BufMut.
|
||||||
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
|
fn put_i64<T: ByteOrder>(&mut self, n: i64) {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
T::write_i64(&mut buf, n);
|
T::write_i64(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes an unsigned n-bytes integer to the BufMut.
|
/// Writes an unsigned n-bytes integer to the BufMut.
|
||||||
@@ -320,7 +311,7 @@ pub trait BufMut {
|
|||||||
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
|
fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
T::write_uint(&mut buf, n, nbytes);
|
T::write_uint(&mut buf, n, nbytes);
|
||||||
self.copy_from_slice(&buf[0..nbytes])
|
self.put_slice(&buf[0..nbytes])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a signed n-bytes integer to the BufMut.
|
/// Writes a signed n-bytes integer to the BufMut.
|
||||||
@@ -330,7 +321,7 @@ pub trait BufMut {
|
|||||||
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
|
fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
T::write_int(&mut buf, n, nbytes);
|
T::write_int(&mut buf, n, nbytes);
|
||||||
self.copy_from_slice(&buf[0..nbytes])
|
self.put_slice(&buf[0..nbytes])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
|
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
|
||||||
@@ -338,7 +329,7 @@ pub trait BufMut {
|
|||||||
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
|
fn put_f32<T: ByteOrder>(&mut self, n: f32) {
|
||||||
let mut buf = [0; 4];
|
let mut buf = [0; 4];
|
||||||
T::write_f32(&mut buf, n);
|
T::write_f32(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
|
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
|
||||||
@@ -346,7 +337,7 @@ pub trait BufMut {
|
|||||||
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
|
fn put_f64<T: ByteOrder>(&mut self, n: f64) {
|
||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
T::write_f64(&mut buf, n);
|
T::write_f64(&mut buf, n);
|
||||||
self.copy_from_slice(&buf)
|
self.put_slice(&buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a "by reference" adaptor for this instance of BufMut
|
/// Creates a "by reference" adaptor for this instance of BufMut
|
||||||
@@ -446,14 +437,26 @@ pub trait Source {
|
|||||||
|
|
||||||
impl<'a> Source for &'a [u8] {
|
impl<'a> Source for &'a [u8] {
|
||||||
fn source<B: BufMut>(self, buf: &mut B) {
|
fn source<B: BufMut>(self, buf: &mut B) {
|
||||||
buf.copy_from_slice(self);
|
buf.put_slice(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Source for &'a str {
|
||||||
|
fn source<B: BufMut>(self, buf: &mut B) {
|
||||||
|
buf.put_slice(self.as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Source for u8 {
|
impl Source for u8 {
|
||||||
fn source<B: BufMut>(self, buf: &mut B) {
|
fn source<B: BufMut>(self, buf: &mut B) {
|
||||||
let src = [self];
|
let src = [self];
|
||||||
buf.copy_from_slice(&src);
|
buf.put_slice(&src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Source for i8 {
|
||||||
|
fn source<B: BufMut>(self, buf: &mut B) {
|
||||||
|
buf.put_slice(&[self as u8])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +587,7 @@ impl<B: BufMut + Sized> io::Write for Writer<B> {
|
|||||||
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
|
||||||
let n = cmp::min(self.buf.remaining_mut(), src.len());
|
let n = cmp::min(self.buf.remaining_mut(), src.len());
|
||||||
|
|
||||||
self.buf.copy_from(&src[0..n]);
|
self.buf.put(&src[0..n]);
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
-182
@@ -1,182 +0,0 @@
|
|||||||
use {Buf, BufMut};
|
|
||||||
use std::{cmp, fmt};
|
|
||||||
|
|
||||||
/// A buffer adapter which limits the bytes read from an underlying value.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Take<T> {
|
|
||||||
inner: T,
|
|
||||||
limit: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A buffer adapter which limits the bytes written from an underlying value.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TakeMut<T> {
|
|
||||||
inner: T,
|
|
||||||
limit: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new<T>(inner: T, limit: usize) -> Take<T> {
|
|
||||||
Take {
|
|
||||||
inner: inner,
|
|
||||||
limit: limit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_mut<T>(inner: T, limit: usize) -> TakeMut<T> {
|
|
||||||
TakeMut {
|
|
||||||
inner: inner,
|
|
||||||
limit: limit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* ===== impl Take =====
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<T> Take<T> {
|
|
||||||
/// Consumes this `Take`, returning the underlying value.
|
|
||||||
pub fn into_inner(self) -> T {
|
|
||||||
self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a reference to the underlying value in this `Take`.
|
|
||||||
pub fn get_ref(&self) -> &T {
|
|
||||||
&self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a mutable reference to the underlying value in this `Take`.
|
|
||||||
pub fn get_mut(&mut self) -> &mut T {
|
|
||||||
&mut self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the maximum number of bytes that are made available from the
|
|
||||||
/// underlying value.
|
|
||||||
pub fn limit(&self) -> usize {
|
|
||||||
self.limit
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the maximum number of bytes that are made available from the
|
|
||||||
/// underlying value.
|
|
||||||
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] {
|
|
||||||
&self.inner.bytes()[..self.limit]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn advance(&mut self, cnt: usize) {
|
|
||||||
let cnt = cmp::min(cnt, self.limit);
|
|
||||||
self.limit -= cnt;
|
|
||||||
self.inner.advance(cnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BufMut> BufMut for Take<T> {
|
|
||||||
fn remaining_mut(&self) -> usize {
|
|
||||||
self.inner.remaining_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
|
||||||
self.inner.bytes_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
|
||||||
self.inner.advance_mut(cnt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BufMut> fmt::Write for Take<T> {
|
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
||||||
BufMut::put_str(self, s);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
|
||||||
fmt::write(self, args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* ===== impl TakeMut =====
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl<T> TakeMut<T> {
|
|
||||||
/// Consumes this `TakeMut`, returning the underlying value.
|
|
||||||
pub fn into_inner(self) -> T {
|
|
||||||
self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a reference to the underlying value in this `TakeMut`.
|
|
||||||
pub fn get_ref(&self) -> &T {
|
|
||||||
&self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a mutable reference to the underlying value in this `TakeMut`.
|
|
||||||
pub fn get_mut(&mut self) -> &mut T {
|
|
||||||
&mut self.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the maximum number of bytes that are made available from the
|
|
||||||
/// underlying value.
|
|
||||||
pub fn limit(&self) -> usize {
|
|
||||||
self.limit
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the maximum number of bytes that are made available from the
|
|
||||||
/// underlying value.
|
|
||||||
pub fn set_limit(&mut self, lim: usize) {
|
|
||||||
self.limit = lim
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Buf> Buf for TakeMut<T> {
|
|
||||||
fn remaining(&self) -> usize {
|
|
||||||
self.inner.remaining()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bytes(&self) -> &[u8] {
|
|
||||||
self.inner.bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn advance(&mut self, cnt: usize) {
|
|
||||||
self.inner.advance(cnt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BufMut> BufMut for TakeMut<T> {
|
|
||||||
fn remaining_mut(&self) -> usize {
|
|
||||||
cmp::min(self.inner.remaining_mut(), self.limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
|
||||||
&mut self.inner.bytes_mut()[..self.limit]
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
|
||||||
let cnt = cmp::min(cnt, self.limit);
|
|
||||||
self.limit -= cnt;
|
|
||||||
self.inner.advance_mut(cnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BufMut> fmt::Write for TakeMut<T> {
|
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
||||||
BufMut::put_str(self, s);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
|
||||||
fmt::write(self, args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+287
-8
@@ -114,9 +114,9 @@ pub struct Bytes {
|
|||||||
///
|
///
|
||||||
/// let mut buf = BytesMut::with_capacity(64);
|
/// let mut buf = BytesMut::with_capacity(64);
|
||||||
///
|
///
|
||||||
/// buf.put_u8(b'h');
|
/// buf.put(b'h');
|
||||||
/// buf.put_u8(b'e');
|
/// buf.put(b'e');
|
||||||
/// buf.put_str("llo");
|
/// buf.put("llo");
|
||||||
///
|
///
|
||||||
/// assert_eq!(&buf[..], b"hello");
|
/// assert_eq!(&buf[..], b"hello");
|
||||||
///
|
///
|
||||||
@@ -489,12 +489,24 @@ impl From<Vec<u8>> for Bytes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<String> for Bytes {
|
||||||
|
fn from(src: String) -> Bytes {
|
||||||
|
BytesMut::from(src).freeze()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [u8]> for Bytes {
|
impl<'a> From<&'a [u8]> for Bytes {
|
||||||
fn from(src: &'a [u8]) -> Bytes {
|
fn from(src: &'a [u8]) -> Bytes {
|
||||||
BytesMut::from(src).freeze()
|
BytesMut::from(src).freeze()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for Bytes {
|
||||||
|
fn from(src: &'a str) -> Bytes {
|
||||||
|
BytesMut::from(src).freeze()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for Bytes {
|
impl PartialEq for Bytes {
|
||||||
fn eq(&self, other: &Bytes) -> bool {
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
self.inner.as_ref() == other.inner.as_ref()
|
self.inner.as_ref() == other.inner.as_ref()
|
||||||
@@ -538,7 +550,7 @@ impl BytesMut {
|
|||||||
/// // `bytes` contains no data, even though there is capacity
|
/// // `bytes` contains no data, even though there is capacity
|
||||||
/// assert_eq!(bytes.len(), 0);
|
/// assert_eq!(bytes.len(), 0);
|
||||||
///
|
///
|
||||||
/// bytes.copy_from_slice(b"hello world");
|
/// bytes.put(&b"hello world"[..]);
|
||||||
///
|
///
|
||||||
/// assert_eq!(&bytes[..], b"hello world");
|
/// assert_eq!(&bytes[..], b"hello world");
|
||||||
/// ```
|
/// ```
|
||||||
@@ -618,7 +630,7 @@ impl BytesMut {
|
|||||||
/// use std::thread;
|
/// use std::thread;
|
||||||
///
|
///
|
||||||
/// let mut b = BytesMut::with_capacity(64);
|
/// let mut b = BytesMut::with_capacity(64);
|
||||||
/// b.put_str("hello world");
|
/// b.put("hello world");
|
||||||
/// let b1 = b.freeze();
|
/// let b1 = b.freeze();
|
||||||
/// let b2 = b1.clone();
|
/// let b2 = b1.clone();
|
||||||
///
|
///
|
||||||
@@ -785,6 +797,63 @@ impl BytesMut {
|
|||||||
pub unsafe fn set_len(&mut self, len: usize) {
|
pub unsafe fn set_len(&mut self, len: usize) {
|
||||||
self.inner.set_len(len)
|
self.inner.set_len(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reserves capacity for at least `additional` more bytes to be inserted
|
||||||
|
/// into the given `BytesMut`.
|
||||||
|
///
|
||||||
|
/// More than `additional` bytes may be reserved in order to avoid frequent
|
||||||
|
/// reallocations. A call to `reserve` may result in an allocation.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use bytes::BytesMut;
|
||||||
|
///
|
||||||
|
/// let mut b = BytesMut::from(&b"hello"[..]);
|
||||||
|
/// b.reserve(64);
|
||||||
|
/// assert!(b.capacity() >= 69);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the new capacity overflows usize.
|
||||||
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
|
self.inner.reserve(additional)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to reclaim ownership of the full buffer.
|
||||||
|
///
|
||||||
|
/// Returns `true` if the reclaim is successful.
|
||||||
|
///
|
||||||
|
/// If the `BytesMut` handle is the only outstanding handle pointing to the
|
||||||
|
/// memory slice, the handle's view will be set to the full memory slice,
|
||||||
|
/// enabling reusing buffer space without allocating.
|
||||||
|
///
|
||||||
|
/// Any data in the `BytesMut` handle will be copied to the start of the
|
||||||
|
/// memory region.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use bytes::BytesMut;
|
||||||
|
///
|
||||||
|
/// let mut bytes = BytesMut::from(
|
||||||
|
/// "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
||||||
|
///
|
||||||
|
/// // Create a new handle to the shared memory region
|
||||||
|
/// let a = bytes.drain_to(5);
|
||||||
|
///
|
||||||
|
/// // Attempting to reclaim here will fail due to `a` still being in
|
||||||
|
/// // existence.
|
||||||
|
/// assert!(!bytes.try_reclaim());
|
||||||
|
/// assert_eq!(bytes.capacity(), 51);
|
||||||
|
///
|
||||||
|
/// // Dropping the handle will allow reclaim to succeed.
|
||||||
|
/// drop(a);
|
||||||
|
/// assert!(bytes.try_reclaim());
|
||||||
|
/// assert_eq!(bytes.capacity(), 56);
|
||||||
|
/// ```
|
||||||
|
pub fn try_reclaim(&mut self) -> bool {
|
||||||
|
self.inner.try_reclaim()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufMut for BytesMut {
|
impl BufMut for BytesMut {
|
||||||
@@ -806,7 +875,7 @@ impl BufMut for BytesMut {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_from_slice(&mut self, src: &[u8]) {
|
fn put_slice(&mut self, src: &[u8]) {
|
||||||
assert!(self.remaining_mut() >= src.len());
|
assert!(self.remaining_mut() >= src.len());
|
||||||
|
|
||||||
let len = src.len();
|
let len = src.len();
|
||||||
@@ -875,6 +944,12 @@ impl From<Vec<u8>> for BytesMut {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<String> for BytesMut {
|
||||||
|
fn from(src: String) -> BytesMut {
|
||||||
|
BytesMut::from(src.into_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [u8]> for BytesMut {
|
impl<'a> From<&'a [u8]> for BytesMut {
|
||||||
fn from(src: &'a [u8]) -> BytesMut {
|
fn from(src: &'a [u8]) -> BytesMut {
|
||||||
if src.len() <= INLINE_CAP {
|
if src.len() <= INLINE_CAP {
|
||||||
@@ -894,12 +969,18 @@ impl<'a> From<&'a [u8]> for BytesMut {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut buf = BytesMut::with_capacity(src.len());
|
let mut buf = BytesMut::with_capacity(src.len());
|
||||||
buf.copy_from_slice(src.as_ref());
|
buf.put(src.as_ref());
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for BytesMut {
|
||||||
|
fn from(src: &'a str) -> BytesMut {
|
||||||
|
BytesMut::from(src.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Bytes> for BytesMut {
|
impl From<Bytes> for BytesMut {
|
||||||
fn from(src: Bytes) -> BytesMut {
|
fn from(src: Bytes) -> BytesMut {
|
||||||
src.try_mut()
|
src.try_mut()
|
||||||
@@ -924,7 +1005,7 @@ impl fmt::Debug for BytesMut {
|
|||||||
|
|
||||||
impl fmt::Write for BytesMut {
|
impl fmt::Write for BytesMut {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
BufMut::put_str(self, s);
|
BufMut::put(self, s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,6 +1301,150 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn reserve(&mut self, additional: usize) {
|
||||||
|
let len = self.len();
|
||||||
|
let rem = self.capacity() - len;
|
||||||
|
|
||||||
|
if additional <= rem {
|
||||||
|
// Nothing more to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.kind() {
|
||||||
|
Kind::Vec => {
|
||||||
|
unsafe {
|
||||||
|
let d = &mut *self.data.get();
|
||||||
|
|
||||||
|
// Promote this `Bytes` to an arc, and clone it
|
||||||
|
let mut v = Vec::from_raw_parts(d.ptr, d.len, d.cap);
|
||||||
|
v.reserve(additional);
|
||||||
|
|
||||||
|
// Update the info
|
||||||
|
d.ptr = v.as_mut_ptr();
|
||||||
|
d.len = v.len();
|
||||||
|
d.cap = v.capacity();
|
||||||
|
|
||||||
|
// Drop the vec reference
|
||||||
|
mem::forget(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kind::Arc => {
|
||||||
|
unsafe {
|
||||||
|
// Compute the new capacity
|
||||||
|
let new_cap = len + additional;
|
||||||
|
|
||||||
|
// Create a new vector to store the data
|
||||||
|
let mut v = Vec::with_capacity(new_cap);
|
||||||
|
|
||||||
|
// Copy the bytes
|
||||||
|
v.extend_from_slice(self.as_ref());
|
||||||
|
|
||||||
|
let d = &mut *self.data.get();
|
||||||
|
|
||||||
|
d.ptr = v.as_mut_ptr();
|
||||||
|
d.len = v.len();
|
||||||
|
d.cap = v.capacity();
|
||||||
|
|
||||||
|
mem::forget(v);
|
||||||
|
|
||||||
|
// Drop the arc reference
|
||||||
|
let _: Arc<UnsafeCell<Vec<u8>>> = mem::transmute(self.arc.get());
|
||||||
|
|
||||||
|
self.arc.set(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kind::Inline => {
|
||||||
|
let new_cap = len + additional;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
if new_cap <= INLINE_CAP {
|
||||||
|
let dst = &mut self.data as *mut _ as *mut u8;
|
||||||
|
let src = self.inline_ptr();
|
||||||
|
|
||||||
|
ptr::copy(src, dst, len);
|
||||||
|
|
||||||
|
let mut a = KIND_INLINE;
|
||||||
|
a |= len << INLINE_LEN_OFFSET;
|
||||||
|
|
||||||
|
self.arc.set(a);
|
||||||
|
} else {
|
||||||
|
let mut v = Vec::with_capacity(new_cap);
|
||||||
|
|
||||||
|
// Copy the bytes
|
||||||
|
v.extend_from_slice(self.as_ref());
|
||||||
|
|
||||||
|
let d = &mut *self.data.get();
|
||||||
|
|
||||||
|
d.ptr = v.as_mut_ptr();
|
||||||
|
d.len = v.len();
|
||||||
|
d.cap = v.capacity();
|
||||||
|
|
||||||
|
mem::forget(v);
|
||||||
|
|
||||||
|
self.arc.set(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kind::Static => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This must take `&mut self` in order to be able to copy memory in the
|
||||||
|
/// inline case.
|
||||||
|
#[inline]
|
||||||
|
fn try_reclaim(&mut self) -> bool {
|
||||||
|
match self.kind() {
|
||||||
|
Kind::Inline => {
|
||||||
|
if self.inline_start() > 0 {
|
||||||
|
// Shift the data back to the front
|
||||||
|
unsafe {
|
||||||
|
let len = self.inline_len();
|
||||||
|
let dst = &mut self.data as *mut _ as *mut u8;
|
||||||
|
let src = self.inline_ptr();
|
||||||
|
|
||||||
|
ptr::copy(src, dst, len);
|
||||||
|
|
||||||
|
let mut a = KIND_INLINE;
|
||||||
|
a |= len << INLINE_LEN_OFFSET;
|
||||||
|
|
||||||
|
self.arc.set(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Kind::Arc => {
|
||||||
|
unsafe {
|
||||||
|
let arc: &mut Shared = mem::transmute(&mut self.arc);
|
||||||
|
|
||||||
|
// Check if mut safe
|
||||||
|
if Arc::get_mut(arc).is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = &mut *arc.get();
|
||||||
|
let d = &mut *self.data.get();
|
||||||
|
|
||||||
|
let len = v.len();
|
||||||
|
let ptr = v.as_mut_ptr();
|
||||||
|
|
||||||
|
ptr::copy(d.ptr, ptr, len);
|
||||||
|
|
||||||
|
d.ptr = ptr;
|
||||||
|
d.len = len;
|
||||||
|
d.cap = v.capacity();
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kind::Vec => {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Kind::Static => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn kind(&self) -> Kind {
|
fn kind(&self) -> Kind {
|
||||||
let arc = self.arc.get();
|
let arc = self.arc.get();
|
||||||
@@ -1283,6 +1508,12 @@ impl PartialEq<[u8]> for BytesMut {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<str> for BytesMut {
|
||||||
|
fn eq(&self, other: &str) -> bool {
|
||||||
|
&**self == other.as_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<BytesMut> for [u8] {
|
impl PartialEq<BytesMut> for [u8] {
|
||||||
fn eq(&self, other: &BytesMut) -> bool {
|
fn eq(&self, other: &BytesMut) -> bool {
|
||||||
*other == *self
|
*other == *self
|
||||||
@@ -1295,12 +1526,24 @@ impl PartialEq<Vec<u8>> for BytesMut {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<String> for BytesMut {
|
||||||
|
fn eq(&self, other: &String) -> bool {
|
||||||
|
*self == &other[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<BytesMut> for Vec<u8> {
|
impl PartialEq<BytesMut> for Vec<u8> {
|
||||||
fn eq(&self, other: &BytesMut) -> bool {
|
fn eq(&self, other: &BytesMut) -> bool {
|
||||||
*other == *self
|
*other == *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<BytesMut> for String {
|
||||||
|
fn eq(&self, other: &BytesMut) -> bool {
|
||||||
|
*other == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
|
impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
|
||||||
where BytesMut: PartialEq<T>
|
where BytesMut: PartialEq<T>
|
||||||
{
|
{
|
||||||
@@ -1315,36 +1558,72 @@ impl<'a> PartialEq<BytesMut> for &'a [u8] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PartialEq<BytesMut> for &'a str {
|
||||||
|
fn eq(&self, other: &BytesMut) -> bool {
|
||||||
|
*other == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<[u8]> for Bytes {
|
impl PartialEq<[u8]> for Bytes {
|
||||||
fn eq(&self, other: &[u8]) -> bool {
|
fn eq(&self, other: &[u8]) -> bool {
|
||||||
self.inner.as_ref() == other
|
self.inner.as_ref() == other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<str> for Bytes {
|
||||||
|
fn eq(&self, other: &str) -> bool {
|
||||||
|
self.inner.as_ref() == other.as_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<Bytes> for [u8] {
|
impl PartialEq<Bytes> for [u8] {
|
||||||
fn eq(&self, other: &Bytes) -> bool {
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
*other == *self
|
*other == *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<Bytes> for str {
|
||||||
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
|
*other == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<Vec<u8>> for Bytes {
|
impl PartialEq<Vec<u8>> for Bytes {
|
||||||
fn eq(&self, other: &Vec<u8>) -> bool {
|
fn eq(&self, other: &Vec<u8>) -> bool {
|
||||||
*self == &other[..]
|
*self == &other[..]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<String> for Bytes {
|
||||||
|
fn eq(&self, other: &String) -> bool {
|
||||||
|
*self == &other[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<Bytes> for Vec<u8> {
|
impl PartialEq<Bytes> for Vec<u8> {
|
||||||
fn eq(&self, other: &Bytes) -> bool {
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
*other == *self
|
*other == *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<Bytes> for String {
|
||||||
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
|
*other == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> PartialEq<Bytes> for &'a [u8] {
|
impl<'a> PartialEq<Bytes> for &'a [u8] {
|
||||||
fn eq(&self, other: &Bytes) -> bool {
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
*other == *self
|
*other == *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PartialEq<Bytes> for &'a str {
|
||||||
|
fn eq(&self, other: &Bytes) -> bool {
|
||||||
|
*other == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
|
impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
|
||||||
where Bytes: PartialEq<T>
|
where Bytes: PartialEq<T>
|
||||||
{
|
{
|
||||||
|
|||||||
+63
@@ -1,4 +1,67 @@
|
|||||||
//! Provides abstractions for working with bytes.
|
//! Provides abstractions for working with bytes.
|
||||||
|
//!
|
||||||
|
//! The `bytes` crate provides an efficient byte buffer structure
|
||||||
|
//! ([`Bytes`](struct.Bytes.html)) and traits for working with buffer
|
||||||
|
//! implementations ([`Buf`](trait.Buf.html), [`BufMut`](trait.BufMut.html)).
|
||||||
|
//!
|
||||||
|
//! # `Bytes`
|
||||||
|
//!
|
||||||
|
//! `Bytes` is an efficient container for storing and operating on continguous
|
||||||
|
//! slices of memory. It is intended for use primarily in networking code, but
|
||||||
|
//! could have applications elsewhere as well.
|
||||||
|
//!
|
||||||
|
//! `Bytes` values facilitate zero-copy network programming by allowing multiple
|
||||||
|
//! `Bytes` objects to point to the same underlying memory. This is managed by
|
||||||
|
//! using a reference count to track when the memory is no longer needed and can
|
||||||
|
//! be freed.
|
||||||
|
//!
|
||||||
|
//! See the [struct docs](struct.Bytes.html) for more details.
|
||||||
|
//!
|
||||||
|
//! # `Buf`, `BufMut`
|
||||||
|
//!
|
||||||
|
//! These two traits provide read and write access to buffers. The underlying
|
||||||
|
//! storage may or may not be in contiguous memory. For example, `Bytes` is a
|
||||||
|
//! buffer that guarantees contiguous memory, but a
|
||||||
|
//! [rope](https://en.wikipedia.org/wiki/Rope_(data_structure)) stores the bytes
|
||||||
|
//! in disjoint chunks. `Buf` and `BufMut` maintain cursors tracking the current
|
||||||
|
//! position in the underlying byte storage. When bytes are read or written, the
|
||||||
|
//! cursor is advanced.
|
||||||
|
//!
|
||||||
|
//! ## Relation with `Read` and `Write`
|
||||||
|
//!
|
||||||
|
//! At first glance, it may seem that `Buf` and `BufMut` overlap in
|
||||||
|
//! functionality with `std::io::Ready` and `std::io::Write`. However, they
|
||||||
|
//! serve different purposes. A buffer is the value that is provided as an
|
||||||
|
//! argument to `Read::read` and `Write::write`. `Read` and `Write` may then
|
||||||
|
//! perform a syscall, which has the potential of failing. Operations on `Buf`
|
||||||
|
//! and `BufMut` are infallible.
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use bytes::{BytesMut, Buf, BufMut};
|
||||||
|
//! use std::io::Cursor;
|
||||||
|
//! use std::thread;
|
||||||
|
//!
|
||||||
|
//! // Allocate a buffer capable of holding 1024 bytes.
|
||||||
|
//! let mut buf = BytesMut::with_capacity(1024);
|
||||||
|
//!
|
||||||
|
//! // Write some data
|
||||||
|
//! buf.put("Hello world");
|
||||||
|
//! buf.put(b'-');
|
||||||
|
//! buf.put("goodbye");
|
||||||
|
//!
|
||||||
|
//! // Freeze the buffer, enabling concurrent access
|
||||||
|
//! let b1 = buf.freeze();
|
||||||
|
//! let b2 = b1.clone();
|
||||||
|
//!
|
||||||
|
//! thread::spawn(move || {
|
||||||
|
//! assert_eq!(&b1[..], b"Hello world-goodbye");
|
||||||
|
//! });
|
||||||
|
//!
|
||||||
|
//! let mut buf = Cursor::new(b2);
|
||||||
|
//! assert_eq!(b'H', buf.get_u8());
|
||||||
|
//! ```
|
||||||
|
|
||||||
#![deny(warnings, missing_docs)]
|
#![deny(warnings, missing_docs)]
|
||||||
|
|
||||||
|
|||||||
+70
-2
@@ -1,10 +1,16 @@
|
|||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut, BufMut};
|
||||||
|
|
||||||
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb";
|
||||||
const SHORT: &'static [u8] = b"hello world";
|
const SHORT: &'static [u8] = b"hello world";
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
const INLINE_CAP: usize = 8 * 3;
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
const INNER_CAP: usize = 4 * 3;
|
||||||
|
|
||||||
fn is_sync<T: Sync>() {}
|
fn is_sync<T: Sync>() {}
|
||||||
fn is_send<T: Send>() {}
|
fn is_send<T: Send>() {}
|
||||||
|
|
||||||
@@ -193,5 +199,67 @@ fn fns_defined_for_bytes_mut() {
|
|||||||
|
|
||||||
// Iterator
|
// Iterator
|
||||||
let v: Vec<u8> = bytes.iter().map(|b| *b).collect();
|
let v: Vec<u8> = bytes.iter().map(|b| *b).collect();
|
||||||
assert_eq!(&v[..], &bytes[..]);
|
assert_eq!(&v[..], bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve() {
|
||||||
|
// Inline -> Vec
|
||||||
|
let mut bytes = BytesMut::with_capacity(8);
|
||||||
|
bytes.put("hello");
|
||||||
|
bytes.reserve(40);
|
||||||
|
assert_eq!(bytes.capacity(), 45);
|
||||||
|
assert_eq!(bytes, "hello");
|
||||||
|
|
||||||
|
// Inline -> Inline
|
||||||
|
let mut bytes = BytesMut::with_capacity(INLINE_CAP);
|
||||||
|
bytes.put("abcdefghijkl");
|
||||||
|
|
||||||
|
let a = bytes.drain_to(10);
|
||||||
|
bytes.reserve(INLINE_CAP - 3);
|
||||||
|
assert_eq!(INLINE_CAP, bytes.capacity());
|
||||||
|
|
||||||
|
assert_eq!(bytes, "kl");
|
||||||
|
assert_eq!(a, "abcdefghij");
|
||||||
|
|
||||||
|
// Vec -> Vec
|
||||||
|
let mut bytes = BytesMut::from(LONG);
|
||||||
|
bytes.reserve(64);
|
||||||
|
assert_eq!(bytes.capacity(), LONG.len() + 64);
|
||||||
|
|
||||||
|
// Arc -> Vec
|
||||||
|
let mut bytes = BytesMut::from(LONG);
|
||||||
|
let a = bytes.drain_to(30);
|
||||||
|
|
||||||
|
bytes.reserve(128);
|
||||||
|
assert_eq!(bytes.capacity(), bytes.len() + 128);
|
||||||
|
|
||||||
|
drop(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_reclaim() {
|
||||||
|
// Inline w/ start at zero
|
||||||
|
let mut bytes = BytesMut::from(&SHORT[..]);
|
||||||
|
assert!(bytes.try_reclaim());
|
||||||
|
assert_eq!(bytes.capacity(), INLINE_CAP);
|
||||||
|
assert_eq!(bytes, SHORT);
|
||||||
|
|
||||||
|
// Inline w/ start not at zero
|
||||||
|
let mut bytes = BytesMut::from(&SHORT[..]);
|
||||||
|
let _ = bytes.drain_to(2);
|
||||||
|
assert_eq!(bytes.capacity(), INLINE_CAP - 2);
|
||||||
|
assert!(bytes.try_reclaim());
|
||||||
|
assert_eq!(bytes.capacity(), INLINE_CAP);
|
||||||
|
assert_eq!(bytes, &SHORT[2..]);
|
||||||
|
|
||||||
|
// Arc
|
||||||
|
let mut bytes = BytesMut::from(&LONG[..]);
|
||||||
|
let a = bytes.drain_to(2);
|
||||||
|
assert!(!bytes.try_reclaim());
|
||||||
|
assert_eq!(bytes.capacity(), LONG.len() - 2);
|
||||||
|
|
||||||
|
drop(a);
|
||||||
|
assert!(bytes.try_reclaim());
|
||||||
|
assert_eq!(bytes.capacity(), LONG.len());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ fn test_vec_as_mut_buf() {
|
|||||||
assert!(buf.bytes_mut().len() >= 64);
|
assert!(buf.bytes_mut().len() >= 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.copy_from(&b"zomg"[..]);
|
buf.put(&b"zomg"[..]);
|
||||||
|
|
||||||
assert_eq!(&buf, b"zomg");
|
assert_eq!(&buf, b"zomg");
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ fn test_vec_as_mut_buf() {
|
|||||||
assert_eq!(buf.capacity(), 64);
|
assert_eq!(buf.capacity(), 64);
|
||||||
|
|
||||||
for _ in 0..16 {
|
for _ in 0..16 {
|
||||||
buf.copy_from(&b"zomg"[..]);
|
buf.put(&b"zomg"[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(buf.len(), 68);
|
assert_eq!(buf.len(), 68);
|
||||||
@@ -32,7 +32,7 @@ fn test_vec_as_mut_buf() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_put_u8() {
|
fn test_put_u8() {
|
||||||
let mut buf = Vec::with_capacity(8);
|
let mut buf = Vec::with_capacity(8);
|
||||||
buf.put_u8(33);
|
buf.put::<u8>(33);
|
||||||
assert_eq!(b"\x21", &buf[..]);
|
assert_eq!(b"\x21", &buf[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user