Struct Bytes
struct Bytes { ... }
A cheaply cloneable and sliceable chunk of contiguous memory.
Bytes is an efficient container for storing and operating on contiguous
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.
Bytes does not have a single implementation. It is an interface, whose
exact behavior is implemented through dynamic dispatch in several underlying
implementations of Bytes.
All Bytes implementations must fulfill the following requirements:
- They are cheaply cloneable and thereby shareable between an unlimited amount of components, for example by modifying a reference count.
- Instances can be sliced to refer to a subset of the original buffer.
use Bytes;
let mut mem = from;
let a = mem.slice;
assert_eq!;
let b = mem.split_to;
assert_eq!;
assert_eq!;
Memory layout
The Bytes struct itself is fairly small, limited to 4 usize fields used
to track information about which segment of the underlying memory the
Bytes handle has access to.
Bytes keeps both a pointer to the shared state containing the full memory
slice and a pointer to the start of the region visible by the handle.
Bytes also tracks the length of its view into the memory.
Sharing
Bytes contains a vtable, which allows implementations of Bytes to define
how sharing/cloning is implemented in detail.
When Bytes::clone() is called, Bytes will call the vtable function for
cloning the backing storage in order to share it behind multiple Bytes
instances.
For Bytes implementations which refer to constant memory (e.g. created
via Bytes::from_static()) the cloning implementation will be a no-op.
For Bytes implementations which point to a reference counted shared storage
(e.g. an Arc<[u8]>), sharing will be implemented by increasing the
reference count.
Due to this mechanism, multiple Bytes instances may point to the same
shared memory region.
Each Bytes instance can point to different sections within that
memory region, and Bytes instances may or may not have overlapping views
into the memory.
The following diagram visualizes a scenario where 2 Bytes instances make
use of an Arc-based backing storage, and provide access to different views:
Arc ptrs ┌─────────┐
________________________ / │ Bytes 2 │
/ └─────────┘
/ ┌───────────┐ | |
|_________/ │ Bytes 1 │ | |
| └───────────┘ | |
| | | ___/ data | tail
| data | tail |/ |
v v v v
┌─────┬─────┬───────────┬───────────────┬─────┐
│ Arc │ │ │ │ │
└─────┴─────┴───────────┴───────────────┴─────┘
Implementations
impl Bytes
const fn new() -> SelfCreates a new empty
Bytes.This will not allocate and the returned
Byteshandle will be empty.Examples
use Bytes; let b = new; assert_eq!;const fn from_static(bytes: &'static [u8]) -> SelfCreates a new
Bytesfrom a static slice.The returned
Byteswill point directly to the static slice. There is no allocating or copying.Examples
use Bytes; let b = from_static; assert_eq!;fn from_owner<T>(owner: T) -> Self where T: AsRef<[u8]> + Send + 'staticCreate [Bytes] with a buffer whose lifetime is controlled via an explicit owner.
A common use case is to zero-copy construct from mapped memory.
# ; # # # # use Bytes; use Mmap; #The
ownerwill be transferred to the constructed [Bytes] object, which will ensure it is dropped once all remaining clones of the constructed object are dropped. The owner will then be responsible for dropping the specified region of memory as part of its [Drop] implementation.Note that converting [Bytes] constructed from an owner into a [BytesMut] will always create a deep copy of the buffer into newly allocated memory.
const fn len(self: &Self) -> usizeReturns the number of bytes contained in this
Bytes.Examples
use Bytes; let b = from; assert_eq!;const fn is_empty(self: &Self) -> boolReturns true if the
Byteshas a length of 0.Examples
use Bytes; let b = new; assert!;fn is_unique(self: &Self) -> boolReturns true if this is the only reference to the data and
Into<BytesMut>would avoid cloning the underlying buffer.Always returns false if the data is backed by a static slice, or an owner.
The result of this method may be invalidated immediately if another thread clones this value while this is being called. Ensure you have unique access to this value (
&mut Bytes) first if you need to be certain the result is valid (i.e. for safety reasons).Examples
use Bytes; let a = from; assert!; let b = a.clone; assert!;fn copy_from_slice(data: &[u8]) -> SelfCreates
Bytesinstance from slice, by copying it.fn slice<impl RangeBounds<usize>: RangeBounds<usize>>(self: &Self, range: impl RangeBounds<usize>) -> SelfReturns a slice of self for the provided range.
This will increment the reference count for the underlying memory and return a new
Byteshandle set to the slice.This operation is
O(1).Examples
use Bytes; let a = from; let b = a.slice; assert_eq!;Panics
Requires that
begin <= endandend <= self.len(), otherwise slicing will panic.fn slice_ref(self: &Self, subset: &[u8]) -> SelfReturns a slice of self that is equivalent to the given
subset.When processing a
Bytesbuffer with other tools, one often gets a&[u8]which is in fact a slice of theBytes, i.e. a subset of it. This function turns that&[u8]into anotherBytes, as if one had calledself.slice()with the offsets that correspond tosubset.This operation is
O(1).Examples
use Bytes; let bytes = from; let as_slice = bytes.as_ref; let subset = &as_slice; let subslice = bytes.slice_ref; assert_eq!;Panics
Requires that the given
subslice is in fact contained within theBytesbuffer; otherwise this function will panic.fn split_off(self: &mut Self, at: usize) -> SelfSplits the bytes into two at the given index.
Afterwards
selfcontains elements[0, at), and the returnedBytescontains elements[at, len). It's guaranteed that the memory does not move, that is, the address ofselfdoes not change, and the address of the returned slice isatbytes after that.This is an
O(1)operation that just increases the reference count and sets a few indices.Examples
use Bytes; let mut a = from; let b = a.split_off; assert_eq!; assert_eq!;Panics
Panics if
at > len.fn split_to(self: &mut Self, at: usize) -> SelfSplits the bytes into two at the given index.
Afterwards
selfcontains elements[at, len), and the returnedBytescontains elements[0, at).This is an
O(1)operation that just increases the reference count and sets a few indices.Examples
use Bytes; let mut a = from; let b = a.split_to; assert_eq!; assert_eq!;Panics
Panics if
at > len.fn truncate(self: &mut Self, len: usize)Shortens the buffer, keeping the first
lenbytes and dropping the rest.If
lenis greater than the buffer's current length, this has no effect.The split_off method can emulate
truncate, but this causes the excess bytes to be returned instead of dropped.Examples
use Bytes; let mut buf = from; buf.truncate; assert_eq!;fn clear(self: &mut Self)Clears the buffer, removing all data.
Examples
use Bytes; let mut buf = from; buf.clear; assert!;fn try_into_mut(self: Self) -> Result<BytesMut, Bytes>Try to convert self into
BytesMut.If
selfis unique for the entire original buffer, this will succeed and return aBytesMutwith the contents ofselfwithout copying. Ifselfis not unique for the entire original buffer, this will fail and return self.This will also always fail if the buffer was constructed via either from_owner or from_static.
Examples
use ; let bytes = from; assert_eq!;
impl AsRef for Bytes
fn as_ref(self: &Self) -> &[u8]
impl Borrow for Bytes
fn borrow(self: &Self) -> &[u8]
impl Buf for Bytes
fn remaining(self: &Self) -> usizefn chunk(self: &Self) -> &[u8]fn advance(self: &mut Self, cnt: usize)fn copy_to_bytes(self: &mut Self, len: usize) -> Self
impl Clone for Bytes
fn clone(self: &Self) -> Bytes
impl Debug for Bytes
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl Default for Bytes
fn default() -> Bytes
impl Deref for Bytes
fn deref(self: &Self) -> &[u8]
impl Drop for Bytes
fn drop(self: &mut Self)
impl Eq for Bytes
impl Freeze for Bytes
impl From for Bytes
fn from(slice: Box<[u8]>) -> Bytes
impl From for Bytes
fn from(vec: Vec<u8>) -> Bytes
impl From for Bytes
fn from(slice: &'static str) -> Bytes
impl From for Bytes
fn from(src: BytesMut) -> Bytes
impl From for Bytes
fn from(slice: &'static [u8]) -> Bytes
impl From for Bytes
fn from(s: String) -> Bytes
impl FromIterator for Bytes
fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self
impl Hash for Bytes
fn hash<H>(self: &Self, state: &mut H) where H: Hasher
impl IntoIterator for Bytes
fn into_iter(self: Self) -> <Self as >::IntoIter
impl LowerHex for Bytes
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl Ord for Bytes
fn cmp(self: &Self, other: &Bytes) -> Ordering
impl PartialEq for Bytes
fn eq(self: &Self, other: &Vec<u8>) -> bool
impl PartialEq for Bytes
fn eq(self: &Self, other: &Bytes) -> bool
impl PartialEq for Bytes
fn eq(self: &Self, other: &BytesMut) -> bool
impl PartialEq for Bytes
fn eq(self: &Self, other: &[u8]) -> bool
impl PartialEq for Bytes
fn eq(self: &Self, other: &str) -> bool
impl PartialEq for Bytes
fn eq(self: &Self, other: &String) -> bool
impl PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &Vec<u8>) -> Option<Ordering>
impl PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &Bytes) -> Option<Ordering>
impl PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &[u8]) -> Option<Ordering>
impl PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &str) -> Option<Ordering>
impl PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &String) -> Option<Ordering>
impl RefUnwindSafe for Bytes
impl Send for Bytes
impl Serialize for Bytes
fn serialize<S>(self: &Self, serializer: S) -> Result<<S as >::Ok, <S as >::Error> where S: Serializer
impl Sync for Bytes
impl Unpin for Bytes
impl UnsafeUnpin for Bytes
impl UnwindSafe for Bytes
impl UpperHex for Bytes
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl<'a, T: ?Sized> PartialEq for Bytes
fn eq(self: &Self, other: &&'a T) -> bool
impl<'a, T: ?Sized> PartialOrd for Bytes
fn partial_cmp(self: &Self, other: &&'a T) -> Option<Ordering>
impl<'de> Deserialize for Bytes
fn deserialize<D>(deserializer: D) -> Result<Bytes, <D as >::Error> where D: Deserializer<'de>
impl<P, T> Receiver for Bytes
impl<T> Any for Bytes
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Bytes
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Bytes
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for Bytes
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> DeserializeOwned for Bytes
impl<T> From for Bytes
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for Bytes
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, U> Into for Bytes
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Bytes
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Bytes
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>