diff --git a/.lock b/.lock new file mode 100644 index 000000000..e69de29bb diff --git a/bytes/all.html b/bytes/all.html new file mode 100644 index 000000000..0848bdaed --- /dev/null +++ b/bytes/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Traits

\ No newline at end of file diff --git a/bytes/buf/buf_impl/trait.Buf.html b/bytes/buf/buf_impl/trait.Buf.html new file mode 100644 index 000000000..af9509861 --- /dev/null +++ b/bytes/buf/buf_impl/trait.Buf.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/trait.Buf.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/buf_mut/trait.BufMut.html b/bytes/buf/buf_mut/trait.BufMut.html new file mode 100644 index 000000000..77242b643 --- /dev/null +++ b/bytes/buf/buf_mut/trait.BufMut.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/trait.BufMut.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/chain/struct.Chain.html b/bytes/buf/chain/struct.Chain.html new file mode 100644 index 000000000..f8ecbf20f --- /dev/null +++ b/bytes/buf/chain/struct.Chain.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.Chain.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/index.html b/bytes/buf/index.html new file mode 100644 index 000000000..c5a39c70c --- /dev/null +++ b/bytes/buf/index.html @@ -0,0 +1,11 @@ +bytes::buf - Rust

Module bytes::buf

source ·
Expand description

Utilities for working with buffers.

+

A buffer is any structure that contains a sequence of bytes. The bytes may +or may not be stored in contiguous memory. This module contains traits used +to abstract over buffers as well as utilities for working with buffer types.

+

Buf, BufMut

+

These are the two foundational traits for abstractly working with buffers. +They can be thought as iterators for byte structures. They offer additional +performance over Iterator by providing an API optimized for byte slices.

+

See Buf and BufMut for more details.

+

Structs

A Chain sequences two buffers.
Iterator over the bytes contained by the buffer.
A BufMut adapter which limits the amount of bytes that can be written +to an underlying buffer.
A Buf adapter which implements io::Read for the inner value.
A Buf adapter which limits the bytes read from an underlying buffer.
Uninitialized byte slice.
A BufMut adapter which implements io::Write for the inner value.

Traits

Read bytes from a buffer.
A trait for values that provide sequential write access to bytes.
\ No newline at end of file diff --git a/bytes/buf/iter/struct.IntoIter.html b/bytes/buf/iter/struct.IntoIter.html new file mode 100644 index 000000000..459f7fe1d --- /dev/null +++ b/bytes/buf/iter/struct.IntoIter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.IntoIter.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/limit/struct.Limit.html b/bytes/buf/limit/struct.Limit.html new file mode 100644 index 000000000..7e57ce537 --- /dev/null +++ b/bytes/buf/limit/struct.Limit.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.Limit.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/reader/struct.Reader.html b/bytes/buf/reader/struct.Reader.html new file mode 100644 index 000000000..8b81eb74c --- /dev/null +++ b/bytes/buf/reader/struct.Reader.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.Reader.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/sidebar-items.js b/bytes/buf/sidebar-items.js new file mode 100644 index 000000000..0fcf33881 --- /dev/null +++ b/bytes/buf/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":[["Chain","A `Chain` sequences two buffers."],["IntoIter","Iterator over the bytes contained by the buffer."],["Limit","A `BufMut` adapter which limits the amount of bytes that can be written to an underlying buffer."],["Reader","A `Buf` adapter which implements `io::Read` for the inner value."],["Take","A `Buf` adapter which limits the bytes read from an underlying buffer."],["UninitSlice","Uninitialized byte slice."],["Writer","A `BufMut` adapter which implements `io::Write` for the inner value."]],"trait":[["Buf","Read bytes from a buffer."],["BufMut","A trait for values that provide sequential write access to bytes."]]}; \ No newline at end of file diff --git a/bytes/buf/struct.Chain.html b/bytes/buf/struct.Chain.html new file mode 100644 index 000000000..b912a675a --- /dev/null +++ b/bytes/buf/struct.Chain.html @@ -0,0 +1,89 @@ +Chain in bytes::buf - Rust

Struct bytes::buf::Chain

source ·
pub struct Chain<T, U> { /* private fields */ }
Expand description

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};
+
+let mut buf = (&b"hello "[..])
+    .chain(&b"world"[..]);
+
+let full: Bytes = buf.copy_to_bytes(11);
+assert_eq!(full[..], b"hello world"[..]);
+

Implementations

Gets a reference to the first underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let buf = (&b"hello"[..])
+    .chain(&b"world"[..]);
+
+assert_eq!(buf.first_ref()[..], b"hello"[..]);
+

Gets a mutable reference to the first underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let mut buf = (&b"hello"[..])
+    .chain(&b"world"[..]);
+
+buf.first_mut().advance(1);
+
+let full = buf.copy_to_bytes(9);
+assert_eq!(full, b"elloworld"[..]);
+

Gets a reference to the last underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let buf = (&b"hello"[..])
+    .chain(&b"world"[..]);
+
+assert_eq!(buf.last_ref()[..], b"world"[..]);
+

Gets a mutable reference to the last underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let mut buf = (&b"hello "[..])
+    .chain(&b"world"[..]);
+
+buf.last_mut().advance(1);
+
+let full = buf.copy_to_bytes(10);
+assert_eq!(full, b"hello orld"[..]);
+

Consumes this Chain, returning the underlying values.

+
Examples
+
use bytes::Buf;
+
+let chain = (&b"hello"[..])
+    .chain(&b"world"[..]);
+
+let (first, last) = chain.into_inner();
+assert_eq!(first[..], b"hello"[..]);
+assert_eq!(last[..], b"world"[..]);
+

Trait Implementations

Returns the number of bytes between the current position and the end of +the buffer. Read more
Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
Advance the internal cursor of the Buf Read more
Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
Returns true if there are any more bytes to consume Read more
Copies bytes from self into dst. Read more
Gets an unsigned 8 bit integer from self. Read more
Gets a signed 8 bit integer from self. Read more
Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
Gets a signed 16 bit integer from self in big-endian byte order. Read more
Gets a signed 16 bit integer from self in little-endian byte order. Read more
Gets a signed 16 bit integer from self in native-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
Gets a signed 32 bit integer from self in big-endian byte order. Read more
Gets a signed 32 bit integer from self in little-endian byte order. Read more
Gets a signed 32 bit integer from self in native-endian byte order. Read more
Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
Gets a signed 64 bit integer from self in big-endian byte order. Read more
Gets a signed 64 bit integer from self in little-endian byte order. Read more
Gets a signed 64 bit integer from self in native-endian byte order. Read more
Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
Gets a signed 128 bit integer from self in big-endian byte order. Read more
Gets a signed 128 bit integer from self in little-endian byte order. Read more
Gets a signed 128 bit integer from self in native-endian byte order. Read more
Gets an unsigned n-byte integer from self in big-endian byte order. Read more
Gets an unsigned n-byte integer from self in little-endian byte order. Read more
Gets an unsigned n-byte integer from self in native-endian byte order. Read more
Gets a signed n-byte integer from self in big-endian byte order. Read more
Gets a signed n-byte integer from self in little-endian byte order. Read more
Gets a signed n-byte integer from self in native-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
Creates an adaptor which will read at most limit bytes from self. Read more
Creates an adaptor which will chain this buffer with another. Read more
Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
Returns the number of bytes that can be written from the current +position until the end of the buffer is reached. Read more
Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation). Read more
Advance the internal cursor of the BufMut Read more
Returns true if there is space in self for more bytes. Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Put cnt bytes val into self. Read more
Writes an unsigned 8 bit integer to self. Read more
Writes a signed 8 bit integer to self. Read more
Writes an unsigned 16 bit integer to self in big-endian byte order. Read more
Writes an unsigned 16 bit integer to self in little-endian byte order. Read more
Writes an unsigned 16 bit integer to self in native-endian byte order. Read more
Writes a signed 16 bit integer to self in big-endian byte order. Read more
Writes a signed 16 bit integer to self in little-endian byte order. Read more
Writes a signed 16 bit integer to self in native-endian byte order. Read more
Writes an unsigned 32 bit integer to self in big-endian byte order. Read more
Writes an unsigned 32 bit integer to self in little-endian byte order. Read more
Writes an unsigned 32 bit integer to self in native-endian byte order. Read more
Writes a signed 32 bit integer to self in big-endian byte order. Read more
Writes a signed 32 bit integer to self in little-endian byte order. Read more
Writes a signed 32 bit integer to self in native-endian byte order. Read more
Writes an unsigned 64 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 64 bit integer to self in little-endian byte order. Read more
Writes an unsigned 64 bit integer to self in native-endian byte order. Read more
Writes a signed 64 bit integer to self in the big-endian byte order. Read more
Writes a signed 64 bit integer to self in little-endian byte order. Read more
Writes a signed 64 bit integer to self in native-endian byte order. Read more
Writes an unsigned 128 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 128 bit integer to self in little-endian byte order. Read more
Writes an unsigned 128 bit integer to self in native-endian byte order. Read more
Writes a signed 128 bit integer to self in the big-endian byte order. Read more
Writes a signed 128 bit integer to self in little-endian byte order. Read more
Writes a signed 128 bit integer to self in native-endian byte order. Read more
Writes an unsigned n-byte integer to self in big-endian byte order. Read more
Writes an unsigned n-byte integer to self in the little-endian byte order. Read more
Writes an unsigned n-byte integer to self in the native-endian byte order. Read more
Writes low nbytes of a signed integer to self in big-endian byte order. Read more
Writes low nbytes of a signed integer to self in little-endian byte order. Read more
Writes low nbytes of a signed integer to self in native-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order. Read more
Creates an adaptor which can write at most limit bytes to self. Read more
Available on crate feature std only.
Creates an adaptor which implements the Write trait for self. Read more
Creates an adapter which will chain this buffer with another. Read more
Formats the value using the given formatter. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/struct.IntoIter.html b/bytes/buf/struct.IntoIter.html new file mode 100644 index 000000000..eed70cda2 --- /dev/null +++ b/bytes/buf/struct.IntoIter.html @@ -0,0 +1,96 @@ +IntoIter in bytes::buf - Rust

Struct bytes::buf::IntoIter

source ·
pub struct IntoIter<T> { /* private fields */ }
Expand description

Iterator over the bytes contained by the buffer.

+

Examples

+

Basic usage:

+ +
use bytes::Bytes;
+
+let buf = Bytes::from(&b"abc"[..]);
+let mut iter = buf.into_iter();
+
+assert_eq!(iter.next(), Some(b'a'));
+assert_eq!(iter.next(), Some(b'b'));
+assert_eq!(iter.next(), Some(b'c'));
+assert_eq!(iter.next(), None);
+

Implementations

Creates an iterator over the bytes contained by the buffer.

+
Examples
+
use bytes::Bytes;
+
+let buf = Bytes::from_static(b"abc");
+let mut iter = buf.into_iter();
+
+assert_eq!(iter.next(), Some(b'a'));
+assert_eq!(iter.next(), Some(b'b'));
+assert_eq!(iter.next(), Some(b'c'));
+assert_eq!(iter.next(), None);
+

Consumes this IntoIter, returning the underlying value.

+
Examples
+
use bytes::{Buf, Bytes};
+
+let buf = Bytes::from(&b"abc"[..]);
+let mut iter = buf.into_iter();
+
+assert_eq!(iter.next(), Some(b'a'));
+
+let buf = iter.into_inner();
+assert_eq!(2, buf.remaining());
+

Gets a reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+
Examples
+
use bytes::{Buf, Bytes};
+
+let buf = Bytes::from(&b"abc"[..]);
+let mut iter = buf.into_iter();
+
+assert_eq!(iter.next(), Some(b'a'));
+
+assert_eq!(2, iter.get_ref().remaining());
+

Gets a mutable reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+
Examples
+
use bytes::{Buf, BytesMut};
+
+let buf = BytesMut::from(&b"abc"[..]);
+let mut iter = buf.into_iter();
+
+assert_eq!(iter.next(), Some(b'a'));
+
+iter.get_mut().advance(1);
+
+assert_eq!(iter.next(), Some(b'c'));
+

Trait Implementations

Formats the value using the given formatter. Read more
Returns the exact remaining length of the iterator. Read more
🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
The type of the elements being iterated over.
Advances the iterator and returns the next value. Read more
Returns the bounds on the remaining length of the iterator. Read more
🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
Consumes the iterator, counting the number of iterations and returning it. Read more
Consumes the iterator, returning the last element. Read more
🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
Returns the nth element of the iterator. Read more
Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
Takes two iterators and creates a new iterator over both in sequence. Read more
‘Zips up’ two iterators into a single iterator of pairs. Read more
🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
Takes a closure and creates an iterator which calls that closure on each +element. Read more
Calls a closure on each element of an iterator. Read more
Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
Creates an iterator that both filters and maps. Read more
Creates an iterator which gives the current iteration count as well as +the next value. Read more
Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
Creates an iterator that skips elements based on a predicate. Read more
Creates an iterator that yields elements based on a predicate. Read more
Creates an iterator that both yields elements based on a predicate and maps. Read more
Creates an iterator that skips the first n elements. Read more
Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
An iterator adapter similar to fold that holds internal state and +produces a new iterator. Read more
Creates an iterator that works like map, but flattens nested structure. Read more
Creates an iterator which ends after the first None. Read more
Does something with each element of an iterator, passing the value on. Read more
Borrows an iterator, rather than consuming it. Read more
Transforms an iterator into a collection. Read more
🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
Consumes an iterator, creating two collections from it. Read more
🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
Folds every element into an accumulator by applying an operation, +returning the final result. Read more
Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
Tests if every element of the iterator matches a predicate. Read more
Tests if any element of the iterator matches a predicate. Read more
Searches for an element of an iterator that satisfies a predicate. Read more
Applies function to the elements of iterator and returns +the first non-none result. Read more
🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
Searches for an element in an iterator, returning its index. Read more
Returns the element that gives the maximum value from the +specified function. Read more
Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
Returns the element that gives the minimum value from the +specified function. Read more
Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
Converts an iterator of pairs into a pair of containers. Read more
Creates an iterator which copies all of its elements. Read more
Creates an iterator which clones all of its elements. Read more
🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
Sums the elements of an iterator. Read more
Iterates over the entire iterator, multiplying all the elements Read more
🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
Lexicographically compares the elements of this Iterator with those +of another. Read more
🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
Determines if the elements of this Iterator are equal to those of +another. Read more
🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
Determines if the elements of this Iterator are unequal to those of +another. Read more
Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/struct.Limit.html b/bytes/buf/struct.Limit.html new file mode 100644 index 000000000..1e6079121 --- /dev/null +++ b/bytes/buf/struct.Limit.html @@ -0,0 +1,31 @@ +Limit in bytes::buf - Rust

Struct bytes::buf::Limit

source ·
pub struct Limit<T> { /* private fields */ }
Expand description

A BufMut adapter which limits the amount of bytes that can be written +to an underlying buffer.

+

Implementations

Consumes this Limit, returning the underlying value.

+

Gets a reference to the underlying BufMut.

+

It is inadvisable to directly write to the underlying BufMut.

+

Gets a mutable reference to the underlying BufMut.

+

It is inadvisable to directly write to the underlying BufMut.

+

Returns the maximum number of bytes that can be written

+
Note
+

If the inner BufMut has fewer bytes than indicated by this method then +that is the actual number of available bytes.

+

Sets the maximum number of bytes that can be written.

+
Note
+

If the inner BufMut has fewer bytes than lim then that is the actual +number of available bytes.

+

Trait Implementations

Returns the number of bytes that can be written from the current +position until the end of the buffer is reached. Read more
Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation). Read more
Advance the internal cursor of the BufMut Read more
Returns true if there is space in self for more bytes. Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Put cnt bytes val into self. Read more
Writes an unsigned 8 bit integer to self. Read more
Writes a signed 8 bit integer to self. Read more
Writes an unsigned 16 bit integer to self in big-endian byte order. Read more
Writes an unsigned 16 bit integer to self in little-endian byte order. Read more
Writes an unsigned 16 bit integer to self in native-endian byte order. Read more
Writes a signed 16 bit integer to self in big-endian byte order. Read more
Writes a signed 16 bit integer to self in little-endian byte order. Read more
Writes a signed 16 bit integer to self in native-endian byte order. Read more
Writes an unsigned 32 bit integer to self in big-endian byte order. Read more
Writes an unsigned 32 bit integer to self in little-endian byte order. Read more
Writes an unsigned 32 bit integer to self in native-endian byte order. Read more
Writes a signed 32 bit integer to self in big-endian byte order. Read more
Writes a signed 32 bit integer to self in little-endian byte order. Read more
Writes a signed 32 bit integer to self in native-endian byte order. Read more
Writes an unsigned 64 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 64 bit integer to self in little-endian byte order. Read more
Writes an unsigned 64 bit integer to self in native-endian byte order. Read more
Writes a signed 64 bit integer to self in the big-endian byte order. Read more
Writes a signed 64 bit integer to self in little-endian byte order. Read more
Writes a signed 64 bit integer to self in native-endian byte order. Read more
Writes an unsigned 128 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 128 bit integer to self in little-endian byte order. Read more
Writes an unsigned 128 bit integer to self in native-endian byte order. Read more
Writes a signed 128 bit integer to self in the big-endian byte order. Read more
Writes a signed 128 bit integer to self in little-endian byte order. Read more
Writes a signed 128 bit integer to self in native-endian byte order. Read more
Writes an unsigned n-byte integer to self in big-endian byte order. Read more
Writes an unsigned n-byte integer to self in the little-endian byte order. Read more
Writes an unsigned n-byte integer to self in the native-endian byte order. Read more
Writes low nbytes of a signed integer to self in big-endian byte order. Read more
Writes low nbytes of a signed integer to self in little-endian byte order. Read more
Writes low nbytes of a signed integer to self in native-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order. Read more
Creates an adaptor which can write at most limit bytes to self. Read more
Available on crate feature std only.
Creates an adaptor which implements the Write trait for self. Read more
Creates an adapter which will chain this buffer with another. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/struct.Reader.html b/bytes/buf/struct.Reader.html new file mode 100644 index 000000000..a4c4e2fb8 --- /dev/null +++ b/bytes/buf/struct.Reader.html @@ -0,0 +1,38 @@ +Reader in bytes::buf - Rust

Struct bytes::buf::Reader

source ·
pub struct Reader<B> { /* private fields */ }
Expand description

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() for more +details.

+

Implementations

Gets a reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let buf = b"hello world".reader();
+
+assert_eq!(b"hello world", buf.get_ref());
+

Gets a mutable reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+

Consumes this Reader, returning the underlying value.

+
Examples
+
use bytes::Buf;
+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());
+

Trait Implementations

Returns the contents of the internal buffer, filling it with more data +from the inner reader if it is empty. Read more
Tells this buffer that amt bytes have been consumed from the buffer, +so they should no longer be returned in calls to read. Read more
🔬This is a nightly-only experimental API. (buf_read_has_data_left)
Check if the underlying Read has any data left to be read. Read more
Read all bytes into buf until the delimiter byte or EOF is reached. Read more
Read all bytes until a newline (the 0xA byte) is reached, and append +them to the provided buffer. You do not need to clear the buffer before +appending. Read more
Returns an iterator over the contents of this reader split on the byte +byte. Read more
Returns an iterator over the lines of this reader. Read more
Formats the value using the given formatter. Read more
Pull some bytes from this source into the specified buffer, returning +how many bytes were read. Read more
Like read, except that it reads into a slice of buffers. Read more
🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored +implementation. Read more
Read all bytes until EOF in this source, placing them into buf. Read more
Read all bytes until EOF in this source, appending them to buf. Read more
Read the exact number of bytes required to fill buf. Read more
🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
Creates a “by reference” adaptor for this instance of Read. Read more
Transforms this Read instance to an Iterator over its bytes. Read more
Creates an adapter which will chain this stream with another. Read more
Creates an adapter which will read at most limit bytes from it. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/struct.Take.html b/bytes/buf/struct.Take.html new file mode 100644 index 000000000..de188297a --- /dev/null +++ b/bytes/buf/struct.Take.html @@ -0,0 +1,84 @@ +Take in bytes::buf - Rust

Struct bytes::buf::Take

source ·
pub struct Take<T> { /* private fields */ }
Expand description

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() for more details.

+

Implementations

Consumes this Take, returning the underlying value.

+
Examples
+
use bytes::{Buf, BufMut};
+
+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"[..]);
+

Gets a reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+
Examples
+
use bytes::Buf;
+
+let buf = b"hello world".take(2);
+
+assert_eq!(11, buf.get_ref().remaining());
+

Gets a mutable reference to the underlying Buf.

+

It is inadvisable to directly read from the underlying Buf.

+
Examples
+
use bytes::{Buf, BufMut};
+
+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"[..]);
+

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
+
use bytes::Buf;
+
+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());
+

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
+
use bytes::{Buf, BufMut};
+
+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"[..]);
+

Trait Implementations

Returns the number of bytes between the current position and the end of +the buffer. Read more
Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
Advance the internal cursor of the Buf Read more
Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
Returns true if there are any more bytes to consume Read more
Copies bytes from self into dst. Read more
Gets an unsigned 8 bit integer from self. Read more
Gets a signed 8 bit integer from self. Read more
Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
Gets a signed 16 bit integer from self in big-endian byte order. Read more
Gets a signed 16 bit integer from self in little-endian byte order. Read more
Gets a signed 16 bit integer from self in native-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
Gets a signed 32 bit integer from self in big-endian byte order. Read more
Gets a signed 32 bit integer from self in little-endian byte order. Read more
Gets a signed 32 bit integer from self in native-endian byte order. Read more
Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
Gets a signed 64 bit integer from self in big-endian byte order. Read more
Gets a signed 64 bit integer from self in little-endian byte order. Read more
Gets a signed 64 bit integer from self in native-endian byte order. Read more
Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
Gets a signed 128 bit integer from self in big-endian byte order. Read more
Gets a signed 128 bit integer from self in little-endian byte order. Read more
Gets a signed 128 bit integer from self in native-endian byte order. Read more
Gets an unsigned n-byte integer from self in big-endian byte order. Read more
Gets an unsigned n-byte integer from self in little-endian byte order. Read more
Gets an unsigned n-byte integer from self in native-endian byte order. Read more
Gets a signed n-byte integer from self in big-endian byte order. Read more
Gets a signed n-byte integer from self in little-endian byte order. Read more
Gets a signed n-byte integer from self in native-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
Creates an adaptor which will read at most limit bytes from self. Read more
Creates an adaptor which will chain this buffer with another. Read more
Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/struct.UninitSlice.html b/bytes/buf/struct.UninitSlice.html new file mode 100644 index 000000000..a9f143c56 --- /dev/null +++ b/bytes/buf/struct.UninitSlice.html @@ -0,0 +1,100 @@ +UninitSlice in bytes::buf - Rust

Struct bytes::buf::UninitSlice

source ·
#[repr(transparent)]
pub struct UninitSlice(_);
Expand description

Uninitialized byte slice.

+

Returned by BufMut::chunk_mut(), the referenced byte slice may be +uninitialized. The wrapper provides safe access without introducing +undefined behavior.

+

The safety invariants of this wrapper are:

+
    +
  1. Reading from an UninitSlice is undefined behavior.
  2. +
  3. Writing uninitialized bytes to an UninitSlice is undefined behavior.
  4. +
+

The difference between &mut UninitSlice and &mut [MaybeUninit<u8>] is +that it is possible in safe code to write uninitialized bytes to an +&mut [MaybeUninit<u8>], which this type prohibits.

+

Implementations

Creates a &mut UninitSlice wrapping a slice of initialised memory.

+
Examples
+
use bytes::buf::UninitSlice;
+
+let mut buffer = [0u8; 64];
+let slice = UninitSlice::new(&mut buffer[..]);
+

Creates a &mut UninitSlice wrapping a slice of uninitialised memory.

+
Examples
+
use bytes::buf::UninitSlice;
+use core::mem::MaybeUninit;
+
+let mut buffer = [MaybeUninit::uninit(); 64];
+let slice = UninitSlice::uninit(&mut buffer[..]);
+
+let mut vec = Vec::with_capacity(1024);
+let spare: &mut UninitSlice = vec.spare_capacity_mut().into();
+

Create a &mut UninitSlice from a pointer and a length.

+
Safety
+

The caller must ensure that ptr references a valid memory region owned +by the caller representing a byte slice for the duration of 'a.

+
Examples
+
use bytes::buf::UninitSlice;
+
+let bytes = b"hello world".to_vec();
+let ptr = bytes.as_ptr() as *mut _;
+let len = bytes.len();
+
+let slice = unsafe { UninitSlice::from_raw_parts_mut(ptr, len) };
+

Write a single byte at the specified offset.

+
Panics
+

The function panics if index is out of bounds.

+
Examples
+
use bytes::buf::UninitSlice;
+
+let mut data = [b'f', b'o', b'o'];
+let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
+
+slice.write_byte(0, b'b');
+
+assert_eq!(b"boo", &data[..]);
+

Copies bytes from src into self.

+

The length of src must be the same as self.

+
Panics
+

The function panics if src has a different length than self.

+
Examples
+
use bytes::buf::UninitSlice;
+
+let mut data = [b'f', b'o', b'o'];
+let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
+
+slice.copy_from_slice(b"bar");
+
+assert_eq!(b"bar", &data[..]);
+

Return a raw pointer to the slice’s buffer.

+
Safety
+

The caller must not read from the referenced memory and must not +write uninitialized bytes to the slice either.

+
Examples
+
use bytes::BufMut;
+
+let mut data = [0, 1, 2];
+let mut slice = &mut data[..];
+let ptr = BufMut::chunk_mut(&mut slice).as_mut_ptr();
+

Return a &mut [MaybeUninit<u8>] to this slice’s buffer.

+
Safety
+

The caller must not read from the referenced memory and must not write +uninitialized bytes to the slice either. This is because BufMut implementation +that created the UninitSlice knows which parts are initialized. Writing uninitialized +bytes to the slice may cause the BufMut to read those bytes and trigger undefined +behavior.

+
Examples
+
use bytes::BufMut;
+
+let mut data = [0, 1, 2];
+let mut slice = &mut data[..];
+unsafe {
+    let uninit_slice = BufMut::chunk_mut(&mut slice).as_uninit_slice_mut();
+};
+

Returns the number of bytes in the slice.

+
Examples
+
use bytes::BufMut;
+
+let mut data = [0, 1, 2];
+let mut slice = &mut data[..];
+let len = BufMut::chunk_mut(&mut slice).len();
+
+assert_eq!(len, 3);
+

Trait Implementations

Formats the value using the given formatter. Read more
Converts to this type from the input type.
Converts to this type from the input type.
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
The returned type after indexing.
Performs the indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more
Performs the mutable indexing (container[index]) operation. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
\ No newline at end of file diff --git a/bytes/buf/struct.Writer.html b/bytes/buf/struct.Writer.html new file mode 100644 index 000000000..8e3d1e182 --- /dev/null +++ b/bytes/buf/struct.Writer.html @@ -0,0 +1,42 @@ +Writer in bytes::buf - Rust

Struct bytes::buf::Writer

source ·
pub struct Writer<B> { /* private fields */ }
Expand description

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() for more +details.

+

Implementations

Gets a reference to the underlying BufMut.

+

It is inadvisable to directly write to the underlying BufMut.

+
Examples
+
use bytes::BufMut;
+
+let buf = Vec::with_capacity(1024).writer();
+
+assert_eq!(1024, buf.get_ref().capacity());
+

Gets a mutable reference to the underlying BufMut.

+

It is inadvisable to directly write to the underlying BufMut.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![].writer();
+
+buf.get_mut().reserve(1024);
+
+assert_eq!(1024, buf.get_ref().capacity());
+

Consumes this Writer, returning the underlying value.

+
Examples
+
use bytes::BufMut;
+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"[..]);
+

Trait Implementations

Formats the value using the given formatter. Read more
Write a buffer into this writer, returning how many bytes were written. Read more
Flush this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
Like write, except that it writes from a slice of buffers. Read more
🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored +implementation. Read more
Attempts to write an entire buffer into this writer. Read more
🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
Writes a formatted string into this writer, returning any error +encountered. Read more
Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/buf/take/struct.Take.html b/bytes/buf/take/struct.Take.html new file mode 100644 index 000000000..4272e0b7d --- /dev/null +++ b/bytes/buf/take/struct.Take.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.Take.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/trait.Buf.html b/bytes/buf/trait.Buf.html new file mode 100644 index 000000000..ed350a136 --- /dev/null +++ b/bytes/buf/trait.Buf.html @@ -0,0 +1,619 @@ +Buf in bytes::buf - Rust

Trait bytes::buf::Buf

source ·
pub trait Buf {
+
Show 48 methods fn remaining(&self) -> usize; + fn chunk(&self) -> &[u8]; + fn advance(&mut self, cnt: usize); + + fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize { ... } + fn has_remaining(&self) -> bool { ... } + fn copy_to_slice(&mut self, dst: &mut [u8]) { ... } + fn get_u8(&mut self) -> u8 { ... } + fn get_i8(&mut self) -> i8 { ... } + fn get_u16(&mut self) -> u16 { ... } + fn get_u16_le(&mut self) -> u16 { ... } + fn get_u16_ne(&mut self) -> u16 { ... } + fn get_i16(&mut self) -> i16 { ... } + fn get_i16_le(&mut self) -> i16 { ... } + fn get_i16_ne(&mut self) -> i16 { ... } + fn get_u32(&mut self) -> u32 { ... } + fn get_u32_le(&mut self) -> u32 { ... } + fn get_u32_ne(&mut self) -> u32 { ... } + fn get_i32(&mut self) -> i32 { ... } + fn get_i32_le(&mut self) -> i32 { ... } + fn get_i32_ne(&mut self) -> i32 { ... } + fn get_u64(&mut self) -> u64 { ... } + fn get_u64_le(&mut self) -> u64 { ... } + fn get_u64_ne(&mut self) -> u64 { ... } + fn get_i64(&mut self) -> i64 { ... } + fn get_i64_le(&mut self) -> i64 { ... } + fn get_i64_ne(&mut self) -> i64 { ... } + fn get_u128(&mut self) -> u128 { ... } + fn get_u128_le(&mut self) -> u128 { ... } + fn get_u128_ne(&mut self) -> u128 { ... } + fn get_i128(&mut self) -> i128 { ... } + fn get_i128_le(&mut self) -> i128 { ... } + fn get_i128_ne(&mut self) -> i128 { ... } + fn get_uint(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_le(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_ne(&mut self, nbytes: usize) -> u64 { ... } + fn get_int(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_le(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_ne(&mut self, nbytes: usize) -> i64 { ... } + fn get_f32(&mut self) -> f32 { ... } + fn get_f32_le(&mut self) -> f32 { ... } + fn get_f32_ne(&mut self) -> f32 { ... } + fn get_f64(&mut self) -> f64 { ... } + fn get_f64_le(&mut self) -> f64 { ... } + fn get_f64_ne(&mut self) -> f64 { ... } + fn copy_to_bytes(&mut self, len: usize) -> Bytes { ... } + fn take(self, limit: usize) -> Take<Self>
    where
        Self: Sized
, + { ... } + fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
    where
        Self: Sized
, + { ... } + fn reader(self) -> Reader<Self>
    where
        Self: Sized
, + { ... } +
}
Expand description

Read bytes from a buffer.

+

A buffer stores bytes in memory such that read operations are 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. It can be thought of as an efficient Iterator for collections of +bytes.

+

The simplest Buf is a &[u8].

+ +
use bytes::Buf;
+
+let mut buf = &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 = [0; 8];
+buf.copy_to_slice(&mut rest);
+
+assert_eq!(&rest[..], &b"lo world"[..]);
+

Required Methods

Returns the number of bytes between the current position and the end of +the buffer.

+

This value is greater than or equal to the length of the slice returned +by chunk().

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.remaining(), 11);
+
+buf.get_u8();
+
+assert_eq!(buf.remaining(), 10);
+
Implementer notes
+

Implementations of remaining should ensure that the return value does +not change unless a call is made to advance or any other function that +is documented to change the Buf’s current position.

+

Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation).

+

This is a lower level function. Most operations are done with other +functions.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk() should return an +empty slice.

+

Advance the internal cursor of the Buf

+

The next call to chunk() will return a slice starting cnt bytes +further into the underlying buffer.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
Panics
+

This function may panic if cnt > self.remaining().

+
Implementer notes
+

It is recommended for implementations of advance to panic if cnt > self.remaining(). If the implementation does not panic, the call must +behave as if cnt == self.remaining().

+

A call with cnt == 0 should never panic and be a no-op.

+

Provided Methods

Available on crate feature std only.

Fills dst with potentially multiple slices starting at self’s +current position.

+

If the Buf is backed by disjoint slices of bytes, chunk_vectored enables +fetching more than one slice at once. dst is a slice of IoSlice +references, enabling the slice to be directly used with writev +without any further conversion. The sum of the lengths of all the +buffers in dst will be less than or equal to Buf::remaining().

+

The entries in dst will be overwritten, but the data contained by +the slices will not be modified. If chunk_vectored does not fill every +entry in dst, then dst is guaranteed to contain all remaining slices +in `self.

+

This is a lower level function. Most operations are done with other +functions.

+
Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk_vectored must return 0 +without mutating dst.

+

Implementations should also take care to properly handle being called +with dst being a zero length slice.

+

Returns true if there are any more bytes to consume

+

This is equivalent to self.remaining() != 0.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"a"[..];
+
+assert!(buf.has_remaining());
+
+buf.get_u8();
+
+assert!(!buf.has_remaining());
+

Copies bytes from self into dst.

+

The cursor is advanced by the number of bytes copied. self must have +enough remaining bytes to fill dst.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+let mut dst = [0; 5];
+
+buf.copy_to_slice(&mut dst);
+assert_eq!(&b"hello"[..], &dst);
+assert_eq!(6, buf.remaining());
+
Panics
+

This function panics if self.remaining() < dst.len().

+

Gets an unsigned 8 bit integer from self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_u8());
+
Panics
+

This function panics if there is no more remaining data in self.

+

Gets a signed 8 bit integer from self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_i8());
+
Panics
+

This function panics if there is no more remaining data in self.

+

Gets an unsigned 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_u16());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_u16_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_u16_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_i16());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_i16_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_i16_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in the big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in the little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_u32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_i32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_u64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_i64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_uint(3));
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_uint_le(3));
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_uint_ne(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_int(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_int_le(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_int_ne(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
+assert_eq!(1.2f32, buf.get_f32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
+assert_eq!(1.2f32, buf.get_f32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\x99\x99\x9A hello",
+    false => b"\x9A\x99\x99\x3F hello",
+};
+assert_eq!(1.2f32, buf.get_f32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
+assert_eq!(1.2f64, buf.get_f64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
+assert_eq!(1.2f64, buf.get_f64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello",
+    false => b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello",
+};
+assert_eq!(1.2f64, buf.get_f64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Consumes len bytes inside self and returns new instance of Bytes +with this data.

+

This function may be optimized by the underlying type to avoid actual +copies. For example, Bytes implementation will do a shallow copy +(ref-count increment).

+
Examples
+
use bytes::Buf;
+
+let bytes = (&b"hello world"[..]).copy_to_bytes(5);
+assert_eq!(&bytes[..], &b"hello"[..]);
+
Panics
+

This function panics if len > self.remaining().

+

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};
+
+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");
+

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;
+
+let mut chain = b"hello "[..].chain(&b"world"[..]);
+
+let full = chain.copy_to_bytes(11);
+assert_eq!(full.chunk(), b"hello world");
+
Available on crate feature std only.

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::{Bytes, Buf};
+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"[..]);
+

Implementations on Foreign Types

Available on crate feature std only.
Available on crate feature std only.

Implementors

\ No newline at end of file diff --git a/bytes/buf/trait.BufMut.html b/bytes/buf/trait.BufMut.html new file mode 100644 index 000000000..43194e7eb --- /dev/null +++ b/bytes/buf/trait.BufMut.html @@ -0,0 +1,732 @@ +BufMut in bytes::buf - Rust

Trait bytes::buf::BufMut

source ·
pub unsafe trait BufMut {
+
Show 48 methods fn remaining_mut(&self) -> usize; + unsafe fn advance_mut(&mut self, cnt: usize); + fn chunk_mut(&mut self) -> &mut UninitSlice; + + fn has_remaining_mut(&self) -> bool { ... } + fn put<T: Buf>(&mut self, src: T)
    where
        Self: Sized
, + { ... } + fn put_slice(&mut self, src: &[u8]) { ... } + fn put_bytes(&mut self, val: u8, cnt: usize) { ... } + fn put_u8(&mut self, n: u8) { ... } + fn put_i8(&mut self, n: i8) { ... } + fn put_u16(&mut self, n: u16) { ... } + fn put_u16_le(&mut self, n: u16) { ... } + fn put_u16_ne(&mut self, n: u16) { ... } + fn put_i16(&mut self, n: i16) { ... } + fn put_i16_le(&mut self, n: i16) { ... } + fn put_i16_ne(&mut self, n: i16) { ... } + fn put_u32(&mut self, n: u32) { ... } + fn put_u32_le(&mut self, n: u32) { ... } + fn put_u32_ne(&mut self, n: u32) { ... } + fn put_i32(&mut self, n: i32) { ... } + fn put_i32_le(&mut self, n: i32) { ... } + fn put_i32_ne(&mut self, n: i32) { ... } + fn put_u64(&mut self, n: u64) { ... } + fn put_u64_le(&mut self, n: u64) { ... } + fn put_u64_ne(&mut self, n: u64) { ... } + fn put_i64(&mut self, n: i64) { ... } + fn put_i64_le(&mut self, n: i64) { ... } + fn put_i64_ne(&mut self, n: i64) { ... } + fn put_u128(&mut self, n: u128) { ... } + fn put_u128_le(&mut self, n: u128) { ... } + fn put_u128_ne(&mut self, n: u128) { ... } + fn put_i128(&mut self, n: i128) { ... } + fn put_i128_le(&mut self, n: i128) { ... } + fn put_i128_ne(&mut self, n: i128) { ... } + fn put_uint(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_le(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_ne(&mut self, n: u64, nbytes: usize) { ... } + fn put_int(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_le(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_ne(&mut self, n: i64, nbytes: usize) { ... } + fn put_f32(&mut self, n: f32) { ... } + fn put_f32_le(&mut self, n: f32) { ... } + fn put_f32_ne(&mut self, n: f32) { ... } + fn put_f64(&mut self, n: f64) { ... } + fn put_f64_le(&mut self, n: f64) { ... } + fn put_f64_ne(&mut self, n: f64) { ... } + fn limit(self, limit: usize) -> Limit<Self>
    where
        Self: Sized
, + { ... } + fn writer(self) -> Writer<Self>
    where
        Self: Sized
, + { ... } + fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
    where
        Self: Sized
, + { ... } +
}
Expand description

A trait for values that provide sequential write access to bytes.

+

Write bytes to a buffer

+

A buffer stores bytes in memory such that write operations are infallible. +The underlying storage may or may not be in contiguous memory. A BufMut +value is a cursor into the buffer. Writing to BufMut advances the cursor +position.

+

The simplest BufMut is a Vec<u8>.

+ +
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put(&b"hello world"[..]);
+
+assert_eq!(buf, b"hello world");
+

Required Methods

Returns the number of bytes that can be written from the current +position until the end of the buffer is reached.

+

This value is greater than or equal to the length of the slice returned +by chunk_mut().

+

Writing to a BufMut may involve allocating more memory on the fly. +Implementations may fail before reaching the number of bytes indicated +by this method if they encounter an allocation failure.

+
Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 10];
+let mut buf = &mut dst[..];
+
+let original_remaining = buf.remaining_mut();
+buf.put(&b"hello"[..]);
+
+assert_eq!(original_remaining - 5, buf.remaining_mut());
+
Implementer notes
+

Implementations of remaining_mut should ensure that the return value +does not change unless a call is made to advance_mut or any other +function that is documented to change the BufMut’s current position.

+
Note
+

remaining_mut may return value smaller than actual available space.

+

Advance the internal cursor of the BufMut

+

The next call to chunk_mut will return a slice starting cnt bytes +further into the underlying buffer.

+
Safety
+

The caller must ensure that the next cnt bytes of chunk are +initialized.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+// Write some data
+buf.chunk_mut()[0..2].copy_from_slice(b"he");
+unsafe { buf.advance_mut(2) };
+
+// write more bytes
+buf.chunk_mut()[0..3].copy_from_slice(b"llo");
+
+unsafe { buf.advance_mut(3); }
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
Panics
+

This function may panic if cnt > self.remaining_mut().

+
Implementer notes
+

It is recommended for implementations of advance_mut to panic if +cnt > self.remaining_mut(). If the implementation does not panic, +the call must behave as if cnt == self.remaining_mut().

+

A call with cnt == 0 should never panic and be a no-op.

+

Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation).

+

This is a lower level function. Most operations are done with other +functions.

+

The returned byte slice may represent uninitialized memory.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+unsafe {
+    // MaybeUninit::as_mut_ptr
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'h');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'e');
+
+    buf.advance_mut(2);
+
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[2..].as_mut_ptr().write(b'o');
+
+    buf.advance_mut(3);
+}
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
Implementer notes
+

This function should never panic. chunk_mut should return an empty +slice if and only if remaining_mut() returns 0. In other words, +chunk_mut() returning an empty slice implies that remaining_mut() will +return 0 and remaining_mut() returning 0 implies that chunk_mut() will +return an empty slice.

+

This function may trigger an out-of-memory abort if it tries to allocate +memory and fails to do so.

+

Provided Methods

Returns true if there is space in self for more bytes.

+

This is equivalent to self.remaining_mut() != 0.

+
Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 5];
+let mut buf = &mut dst[..];
+
+assert!(buf.has_remaining_mut());
+
+buf.put(&b"hello"[..]);
+
+assert!(!buf.has_remaining_mut());
+

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put_u8(b'h');
+buf.put(&b"ello"[..]);
+buf.put(&b" world"[..]);
+
+assert_eq!(buf, b"hello world");
+
Panics
+

Panics if self does not have enough capacity to contain src.

+

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+

self must have enough remaining capacity to contain all of src.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_slice(b"hello");
+
+    assert_eq!(1, buf.remaining_mut());
+}
+
+assert_eq!(b"hello\0", &dst);
+

Put cnt bytes val into self.

+

Logically equivalent to calling self.put_u8(val) cnt times, but may work faster.

+

self must have at least cnt remaining capacity.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_bytes(b'a', 4);
+
+    assert_eq!(2, buf.remaining_mut());
+}
+
+assert_eq!(b"aaaa\0\0", &dst);
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 8 bit integer to self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u8(0x01);
+assert_eq!(buf, b"\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 8 bit integer to self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i8(0x01);
+assert_eq!(buf, b"\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned n-byte integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint(0x010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an unsigned n-byte integer to self in the little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_le(0x010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an unsigned n-byte integer to self in the native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int(0x0504010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_le(0x0504010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32(1.2f32);
+assert_eq!(buf, b"\x3F\x99\x99\x9A");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_le(1.2f32);
+assert_eq!(buf, b"\x9A\x99\x99\x3F");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_ne(1.2f32);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\x99\x99\x9A");
+} else {
+    assert_eq!(buf, b"\x9A\x99\x99\x3F");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64(1.2f64);
+assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_le(1.2f64);
+assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_ne(1.2f64);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+} else {
+    assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Creates an adaptor which can write at most limit bytes to self.

+
Examples
+
use bytes::BufMut;
+
+let arr = &mut [0u8; 128][..];
+assert_eq!(arr.remaining_mut(), 128);
+
+let dst = arr.limit(10);
+assert_eq!(dst.remaining_mut(), 10);
+
Available on crate feature std only.

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;
+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"[..]);
+

Creates an adapter which will chain this buffer with another.

+

The returned BufMut instance will first write to all bytes from +self. Afterwards, it will write to next.

+
Examples
+
use bytes::BufMut;
+
+let mut a = [0u8; 5];
+let mut b = [0u8; 6];
+
+let mut chain = (&mut a[..]).chain_mut(&mut b[..]);
+
+chain.put_slice(b"hello world");
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b" world");
+

Implementations on Foreign Types

Implementors

\ No newline at end of file diff --git a/bytes/buf/uninit_slice/struct.UninitSlice.html b/bytes/buf/uninit_slice/struct.UninitSlice.html new file mode 100644 index 000000000..576f5ff1b --- /dev/null +++ b/bytes/buf/uninit_slice/struct.UninitSlice.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.UninitSlice.html...

+ + + \ No newline at end of file diff --git a/bytes/buf/writer/struct.Writer.html b/bytes/buf/writer/struct.Writer.html new file mode 100644 index 000000000..3a3ba29ac --- /dev/null +++ b/bytes/buf/writer/struct.Writer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../bytes/buf/struct.Writer.html...

+ + + \ No newline at end of file diff --git a/bytes/bytes/struct.Bytes.html b/bytes/bytes/struct.Bytes.html new file mode 100644 index 000000000..4b3bc3a80 --- /dev/null +++ b/bytes/bytes/struct.Bytes.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bytes/struct.Bytes.html...

+ + + \ No newline at end of file diff --git a/bytes/bytes_mut/struct.BytesMut.html b/bytes/bytes_mut/struct.BytesMut.html new file mode 100644 index 000000000..45ba8f32e --- /dev/null +++ b/bytes/bytes_mut/struct.BytesMut.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bytes/struct.BytesMut.html...

+ + + \ No newline at end of file diff --git a/bytes/index.html b/bytes/index.html new file mode 100644 index 000000000..b3cadbf2a --- /dev/null +++ b/bytes/index.html @@ -0,0 +1,50 @@ +bytes - Rust

Crate bytes

source ·
Expand description

Provides abstractions for working with bytes.

+

The bytes crate provides an efficient byte buffer structure +(Bytes) and traits for working with buffer +implementations (Buf, BufMut).

+

Bytes

+

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. This is managed by +using a reference count to track when the memory is no longer needed and can +be freed.

+

A Bytes handle can be created directly from an existing byte store (such as &[u8] +or Vec<u8>), but usually a BytesMut is used first and written to. For +example:

+ +
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(1024);
+buf.put(&b"hello world"[..]);
+buf.put_u16(1234);
+
+let a = buf.split();
+assert_eq!(a, b"hello world\x04\xD2"[..]);
+
+buf.put(&b"goodbye world"[..]);
+
+let b = buf.split();
+assert_eq!(b, b"goodbye world"[..]);
+
+assert_eq!(buf.capacity(), 998);
+

In the above example, only a single buffer of 1024 is allocated. The handles +a and b will share the underlying buffer and maintain indices tracking +the view into the buffer represented by the handle.

+

See the struct docs 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 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::Read 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.

+

Modules

Utilities for working with buffers.

Structs

A cheaply cloneable and sliceable chunk of contiguous memory.
A unique reference to a contiguous slice of memory.

Traits

Read bytes from a buffer.
A trait for values that provide sequential write access to bytes.
\ No newline at end of file diff --git a/bytes/sidebar-items.js b/bytes/sidebar-items.js new file mode 100644 index 000000000..fbfe2cf25 --- /dev/null +++ b/bytes/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":[["buf","Utilities for working with buffers."]],"struct":[["Bytes","A cheaply cloneable and sliceable chunk of contiguous memory."],["BytesMut","A unique reference to a contiguous slice of memory."]],"trait":[["Buf","Read bytes from a buffer."],["BufMut","A trait for values that provide sequential write access to bytes."]]}; \ No newline at end of file diff --git a/bytes/struct.Bytes.html b/bytes/struct.Bytes.html new file mode 100644 index 000000000..4c5e72cf8 --- /dev/null +++ b/bytes/struct.Bytes.html @@ -0,0 +1,1182 @@ +Bytes in bytes - Rust

Struct bytes::Bytes

source ·
pub struct Bytes { /* private fields */ }
Expand description

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::Bytes;
+
+let mut mem = Bytes::from("Hello world");
+let a = mem.slice(0..5);
+
+assert_eq!(a, "Hello");
+
+let b = mem.split_to(6);
+
+assert_eq!(mem, "world");
+assert_eq!(b, "Hello ");
+

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

Creates a new empty Bytes.

+

This will not allocate and the returned Bytes handle will be empty.

+
Examples
+
use bytes::Bytes;
+
+let b = Bytes::new();
+assert_eq!(&b[..], b"");
+

Creates a new Bytes from a static slice.

+

The returned Bytes will point directly to the static slice. There is +no allocating or copying.

+
Examples
+
use bytes::Bytes;
+
+let b = Bytes::from_static(b"hello");
+assert_eq!(&b[..], b"hello");
+

Returns the number of bytes contained in this Bytes.

+
Examples
+
use bytes::Bytes;
+
+let b = Bytes::from(&b"hello"[..]);
+assert_eq!(b.len(), 5);
+

Returns true if the Bytes has a length of 0.

+
Examples
+
use bytes::Bytes;
+
+let b = Bytes::new();
+assert!(b.is_empty());
+

Returns true if this is the only reference to the data.

+

Always returns false if the data is backed by a static slice.

+

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::Bytes;
+
+let a = Bytes::from(vec![1, 2, 3]);
+assert!(a.is_unique());
+let b = a.clone();
+assert!(!a.is_unique());
+

Creates Bytes instance from slice, by copying it.

+

Returns a slice of self for the provided range.

+

This will increment the reference count for the underlying memory and +return a new Bytes handle set to the slice.

+

This operation is O(1).

+
Examples
+
use bytes::Bytes;
+
+let a = Bytes::from(&b"hello world"[..]);
+let b = a.slice(2..5);
+
+assert_eq!(&b[..], b"llo");
+
Panics
+

Requires that begin <= end and end <= self.len(), otherwise slicing +will panic.

+

Returns a slice of self that is equivalent to the given subset.

+

When processing a Bytes buffer with other tools, one often gets a +&[u8] which is in fact a slice of the Bytes, i.e. a subset of it. +This function turns that &[u8] into another Bytes, as if one had +called self.slice() with the offsets that correspond to subset.

+

This operation is O(1).

+
Examples
+
use bytes::Bytes;
+
+let bytes = Bytes::from(&b"012345678"[..]);
+let as_slice = bytes.as_ref();
+let subset = &as_slice[2..6];
+let subslice = bytes.slice_ref(&subset);
+assert_eq!(&subslice[..], b"2345");
+
Panics
+

Requires that the given sub slice is in fact contained within the +Bytes buffer; otherwise this function will panic.

+

Splits the bytes into two at the given index.

+

Afterwards self contains elements [0, at), and the returned Bytes +contains elements [at, len).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
Examples
+
use bytes::Bytes;
+
+let mut a = Bytes::from(&b"hello world"[..]);
+let b = a.split_off(5);
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b" world");
+
Panics
+

Panics if at > len.

+

Splits the bytes into two at the given index.

+

Afterwards self contains elements [at, len), and the returned +Bytes contains elements [0, at).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
Examples
+
use bytes::Bytes;
+
+let mut a = Bytes::from(&b"hello world"[..]);
+let b = a.split_to(5);
+
+assert_eq!(&a[..], b" world");
+assert_eq!(&b[..], b"hello");
+
Panics
+

Panics if at > len.

+

Shortens the buffer, keeping the first len bytes and dropping the +rest.

+

If len is 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::Bytes;
+
+let mut buf = Bytes::from(&b"hello world"[..]);
+buf.truncate(5);
+assert_eq!(buf, b"hello"[..]);
+

Clears the buffer, removing all data.

+
Examples
+
use bytes::Bytes;
+
+let mut buf = Bytes::from(&b"hello world"[..]);
+buf.clear();
+assert!(buf.is_empty());
+

Methods from Deref<Target = [u8]>

Checks if all bytes in this slice are within the ASCII range.

+

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +This behaves similarly to contains if this slice is sorted.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+

Binary searches this slice with a comparator function. +This behaves similarly to contains if this slice is sorted.

+

The comparator function should implement an order consistent +with the sort order of the underlying slice, returning an +order code that indicates whether its argument is Less, +Equal or Greater the desired target.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

Binary searches this slice with a key extraction function. +This behaves similarly to contains if this slice is sorted.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The method may make the middle slice the greatest +length possible for a given type and input slice, but only your algorithm’s performance +should depend on that, not its correctness. It is permissible for all of the input data to +be returned as the prefix or suffix slice.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
🔬This is a nightly-only experimental API. (allocator_api)

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+

Creates a vector by repeating a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations

Converts this type into a shared reference of the (usually inferred) input type.
Immutably borrows from an owned value. Read more
Returns the number of bytes between the current position and the end of +the buffer. Read more
Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
Advance the internal cursor of the Buf Read more
Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
Returns true if there are any more bytes to consume Read more
Copies bytes from self into dst. Read more
Gets an unsigned 8 bit integer from self. Read more
Gets a signed 8 bit integer from self. Read more
Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
Gets a signed 16 bit integer from self in big-endian byte order. Read more
Gets a signed 16 bit integer from self in little-endian byte order. Read more
Gets a signed 16 bit integer from self in native-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
Gets a signed 32 bit integer from self in big-endian byte order. Read more
Gets a signed 32 bit integer from self in little-endian byte order. Read more
Gets a signed 32 bit integer from self in native-endian byte order. Read more
Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
Gets a signed 64 bit integer from self in big-endian byte order. Read more
Gets a signed 64 bit integer from self in little-endian byte order. Read more
Gets a signed 64 bit integer from self in native-endian byte order. Read more
Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
Gets a signed 128 bit integer from self in big-endian byte order. Read more
Gets a signed 128 bit integer from self in little-endian byte order. Read more
Gets a signed 128 bit integer from self in native-endian byte order. Read more
Gets an unsigned n-byte integer from self in big-endian byte order. Read more
Gets an unsigned n-byte integer from self in little-endian byte order. Read more
Gets an unsigned n-byte integer from self in native-endian byte order. Read more
Gets a signed n-byte integer from self in big-endian byte order. Read more
Gets a signed n-byte integer from self in little-endian byte order. Read more
Gets a signed n-byte integer from self in native-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
Creates an adaptor which will read at most limit bytes from self. Read more
Creates an adaptor which will chain this buffer with another. Read more
Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
The resulting type after dereferencing.
Dereferences the value.
Deserialize this value from the given Serde deserializer. Read more
Executes the destructor for this type. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Creates a value from an iterator. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
Formats the value using the given formatter.
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
Serialize this value into the given Serde serializer. Read more
Formats the value using the given formatter.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/struct.BytesMut.html b/bytes/struct.BytesMut.html new file mode 100644 index 000000000..cf5ba931d --- /dev/null +++ b/bytes/struct.BytesMut.html @@ -0,0 +1,2452 @@ +BytesMut in bytes - Rust

Struct bytes::BytesMut

source ·
pub struct BytesMut { /* private fields */ }
Expand description

A unique reference to a contiguous slice of memory.

+

BytesMut represents a unique view into a potentially shared memory region. +Given the uniqueness guarantee, owners of BytesMut handles are able to +mutate the memory.

+

BytesMut can be thought of as containing a buf: Arc<Vec<u8>>, an offset +into buf, a slice length, and a guarantee that no other BytesMut for the +same buf overlaps with its slice. That guarantee means that a write lock +is not required.

+

Growth

+

BytesMut’s BufMut implementation will implicitly grow its buffer as +necessary. However, explicitly reserving the required space up-front before +a series of inserts will be more efficient.

+

Examples

+
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(64);
+
+buf.put_u8(b'h');
+buf.put_u8(b'e');
+buf.put(&b"llo"[..]);
+
+assert_eq!(&buf[..], b"hello");
+
+// Freeze the buffer so that it can be shared
+let a = buf.freeze();
+
+// This does not allocate, instead `b` points to the same memory.
+let b = a.clone();
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b"hello");
+

Implementations

Creates a new BytesMut with the specified capacity.

+

The returned BytesMut will be able to hold at least capacity bytes +without reallocating.

+

It is important to note that this function does not specify the length +of the returned BytesMut, but only the capacity.

+
Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut bytes = BytesMut::with_capacity(64);
+
+// `bytes` contains no data, even though there is capacity
+assert_eq!(bytes.len(), 0);
+
+bytes.put(&b"hello world"[..]);
+
+assert_eq!(&bytes[..], b"hello world");
+

Creates a new BytesMut with default capacity.

+

Resulting object has length 0 and unspecified capacity. +This function does not allocate.

+
Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut bytes = BytesMut::new();
+
+assert_eq!(0, bytes.len());
+
+bytes.reserve(2);
+bytes.put_slice(b"xy");
+
+assert_eq!(&b"xy"[..], &bytes[..]);
+

Returns the number of bytes contained in this BytesMut.

+
Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::from(&b"hello"[..]);
+assert_eq!(b.len(), 5);
+

Returns true if the BytesMut has a length of 0.

+
Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::with_capacity(64);
+assert!(b.is_empty());
+

Returns the number of bytes the BytesMut can hold without reallocating.

+
Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::with_capacity(64);
+assert_eq!(b.capacity(), 64);
+

Converts self into an immutable Bytes.

+

The conversion is zero cost and is used to indicate that the slice +referenced by the handle will no longer be mutated. Once the conversion +is done, the handle can be cloned and shared across threads.

+
Examples
+
use bytes::{BytesMut, BufMut};
+use std::thread;
+
+let mut b = BytesMut::with_capacity(64);
+b.put(&b"hello world"[..]);
+let b1 = b.freeze();
+let b2 = b1.clone();
+
+let th = thread::spawn(move || {
+    assert_eq!(&b1[..], b"hello world");
+});
+
+assert_eq!(&b2[..], b"hello world");
+th.join().unwrap();
+

Creates a new BytesMut, which is initialized with zero.

+
Examples
+
use bytes::BytesMut;
+
+let zeros = BytesMut::zeroed(42);
+
+assert_eq!(zeros.len(), 42);
+zeros.into_iter().for_each(|x| assert_eq!(x, 0));
+

Splits the bytes into two at the given index.

+

Afterwards self contains elements [0, at), and the returned +BytesMut contains elements [at, capacity).

+

This is an O(1) operation that just increases the reference count +and sets a few indices.

+
Examples
+
use bytes::BytesMut;
+
+let mut a = BytesMut::from(&b"hello world"[..]);
+let mut b = a.split_off(5);
+
+a[0] = b'j';
+b[0] = b'!';
+
+assert_eq!(&a[..], b"jello");
+assert_eq!(&b[..], b"!world");
+
Panics
+

Panics if at > capacity.

+

Removes the bytes from the current view, returning them in a new +BytesMut handle.

+

Afterwards, self will be empty, but will retain any additional +capacity that it had before the operation. This is identical to +self.split_to(self.len()).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(1024);
+buf.put(&b"hello world"[..]);
+
+let other = buf.split();
+
+assert!(buf.is_empty());
+assert_eq!(1013, buf.capacity());
+
+assert_eq!(other, b"hello world"[..]);
+

Splits the buffer into two at the given index.

+

Afterwards self contains elements [at, len), and the returned BytesMut +contains elements [0, at).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
Examples
+
use bytes::BytesMut;
+
+let mut a = BytesMut::from(&b"hello world"[..]);
+let mut b = a.split_to(5);
+
+a[0] = b'!';
+b[0] = b'j';
+
+assert_eq!(&a[..], b"!world");
+assert_eq!(&b[..], b"jello");
+
Panics
+

Panics if at > len.

+

Shortens the buffer, keeping the first len bytes and dropping the +rest.

+

If len is greater than the buffer’s current length, this has no +effect.

+

Existing underlying capacity is preserved.

+

The split_off method can emulate truncate, but this causes the +excess bytes to be returned instead of dropped.

+
Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello world"[..]);
+buf.truncate(5);
+assert_eq!(buf, b"hello"[..]);
+

Clears the buffer, removing all data. Existing capacity is preserved.

+
Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello world"[..]);
+buf.clear();
+assert!(buf.is_empty());
+

Resizes the buffer so that len is equal to new_len.

+

If new_len is greater than len, the buffer is extended by the +difference with each additional byte set to value. If new_len is +less than len, the buffer is simply truncated.

+
Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::new();
+
+buf.resize(3, 0x1);
+assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
+
+buf.resize(2, 0x2);
+assert_eq!(&buf[..], &[0x1, 0x1]);
+
+buf.resize(4, 0x3);
+assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
+

Sets the length of the buffer.

+

This will explicitly set the size of the buffer without actually +modifying the data, so it is up to the caller to ensure that the data +has been initialized.

+
Examples
+
use bytes::BytesMut;
+
+let mut b = BytesMut::from(&b"hello world"[..]);
+
+unsafe {
+    b.set_len(5);
+}
+
+assert_eq!(&b[..], b"hello");
+
+unsafe {
+    b.set_len(11);
+}
+
+assert_eq!(&b[..], b"hello world");
+

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.

+

Before allocating new buffer space, the function will attempt to reclaim +space in the existing buffer. If the current handle references a view +into a larger original buffer, and all other handles referencing part +of the same original buffer have been dropped, then the current view +can be copied/shifted to the front of the buffer and the handle can take +ownership of the full buffer, provided that the full buffer is large +enough to fit the requested additional capacity.

+

This optimization will only happen if shifting the data from the current +view to the front of the buffer is not too expensive in terms of the +(amortized) time required. The precise condition is subject to change; +as of now, the length of the data being shifted needs to be at least as +large as the distance that it’s shifted by. If the current view is empty +and the original buffer is large enough to fit the requested additional +capacity, then reallocations will never happen.

+
Examples
+

In the following example, a new buffer is allocated.

+ +
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello"[..]);
+buf.reserve(64);
+assert!(buf.capacity() >= 69);
+

In the following example, the existing buffer is reclaimed.

+ +
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(128);
+buf.put(&[0; 64][..]);
+
+let ptr = buf.as_ptr();
+let other = buf.split();
+
+assert!(buf.is_empty());
+assert_eq!(buf.capacity(), 64);
+
+drop(other);
+buf.reserve(128);
+
+assert_eq!(buf.capacity(), 128);
+assert_eq!(buf.as_ptr(), ptr);
+
Panics
+

Panics if the new capacity overflows usize.

+

Appends given bytes to this BytesMut.

+

If this BytesMut object does not have enough capacity, it is resized +first.

+
Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::with_capacity(0);
+buf.extend_from_slice(b"aaabbb");
+buf.extend_from_slice(b"cccddd");
+
+assert_eq!(b"aaabbbcccddd", &buf[..]);
+

Absorbs a BytesMut that was previously split off.

+

If the two BytesMut objects were previously contiguous and not mutated +in a way that causes re-allocation i.e., if other was created by +calling split_off on this BytesMut, then this is an O(1) operation +that just decreases a reference count and sets a few indices. +Otherwise this method degenerates to +self.extend_from_slice(other.as_ref()).

+
Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::with_capacity(64);
+buf.extend_from_slice(b"aaabbbcccddd");
+
+let split = buf.split_off(6);
+assert_eq!(b"aaabbb", &buf[..]);
+assert_eq!(b"cccddd", &split[..]);
+
+buf.unsplit(split);
+assert_eq!(b"aaabbbcccddd", &buf[..]);
+

Returns the remaining spare capacity of the buffer as a slice of MaybeUninit<u8>.

+

The returned slice can be used to fill the buffer with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
Examples
+
use bytes::BytesMut;
+
+// Allocate buffer big enough for 10 bytes.
+let mut buf = BytesMut::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = buf.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 bytes of the buffer as being initialized.
+unsafe {
+    buf.set_len(3);
+}
+
+assert_eq!(&buf[..], &[0, 1, 2]);
+

Methods from Deref<Target = [u8]>

Checks if all bytes in this slice are within the ASCII range.

+

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+

Returns a mutable pointer to the last item in the slice.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

Swaps two elements in the slice.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Panics
+

Panics if a or b are out of bounds.

+
Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+

Reverses the order of elements in the slice, in place.

+
Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an +index from the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +This behaves similarly to contains if this slice is sorted.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+

Binary searches this slice with a comparator function. +This behaves similarly to contains if this slice is sorted.

+

The comparator function should implement an order consistent +with the sort order of the underlying slice, returning an +order code that indicates whether its argument is Less, +Equal or Greater the desired target.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

Binary searches this slice with a key extraction function. +This behaves similarly to contains if this slice is sorted.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+

Reorder the slice such that the element at index is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and O(n) worst-case. This function is also/ known as “kth +element” in other libraries. It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
Current implementation
+

The current algorithm is based on the quickselect portion of the same quicksort algorithm +used for sort_unstable.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+

Reorder the slice with a comparator function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and O(n) worst-case. This function +is also known as “kth element” in other libraries. It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is based on the quickselect portion of the same quicksort algorithm +used for sort_unstable.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+

Reorder the slice with a key extraction function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and O(n) worst-case. This function +is also known as “kth element” in other libraries. It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is based on the quickselect portion of the same quicksort algorithm +used for sort_unstable.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotate a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+

Fills self with elements by cloning value.

+
Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+

Copies the elements from src into self.

+

The length of src must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The method may make the middle slice the greatest +length possible for a given type and input slice, but only your algorithm’s performance +should depend on that, not its correctness. It is permissible for all of the input data to +be returned as the prefix or suffix slice.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The method may make the middle slice the greatest +length possible for a given type and input slice, but only your algorithm’s performance +should depend on that, not its correctness. It is permissible for all of the input data to +be returned as the prefix or suffix slice.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
🔬This is a nightly-only experimental API. (allocator_api)

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+

Creates a vector by repeating a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations

Converts this type into a mutable reference of the (usually inferred) input type.
Converts this type into a shared reference of the (usually inferred) input type.
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Returns the number of bytes between the current position and the end of +the buffer. Read more
Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
Advance the internal cursor of the Buf Read more
Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
Returns true if there are any more bytes to consume Read more
Copies bytes from self into dst. Read more
Gets an unsigned 8 bit integer from self. Read more
Gets a signed 8 bit integer from self. Read more
Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
Gets a signed 16 bit integer from self in big-endian byte order. Read more
Gets a signed 16 bit integer from self in little-endian byte order. Read more
Gets a signed 16 bit integer from self in native-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
Gets a signed 32 bit integer from self in big-endian byte order. Read more
Gets a signed 32 bit integer from self in little-endian byte order. Read more
Gets a signed 32 bit integer from self in native-endian byte order. Read more
Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
Gets a signed 64 bit integer from self in big-endian byte order. Read more
Gets a signed 64 bit integer from self in little-endian byte order. Read more
Gets a signed 64 bit integer from self in native-endian byte order. Read more
Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
Gets a signed 128 bit integer from self in big-endian byte order. Read more
Gets a signed 128 bit integer from self in little-endian byte order. Read more
Gets a signed 128 bit integer from self in native-endian byte order. Read more
Gets an unsigned n-byte integer from self in big-endian byte order. Read more
Gets an unsigned n-byte integer from self in little-endian byte order. Read more
Gets an unsigned n-byte integer from self in native-endian byte order. Read more
Gets a signed n-byte integer from self in big-endian byte order. Read more
Gets a signed n-byte integer from self in little-endian byte order. Read more
Gets a signed n-byte integer from self in native-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
Creates an adaptor which will read at most limit bytes from self. Read more
Creates an adaptor which will chain this buffer with another. Read more
Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
Returns the number of bytes that can be written from the current +position until the end of the buffer is reached. Read more
Advance the internal cursor of the BufMut Read more
Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation). Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
Put cnt bytes val into self. Read more
Returns true if there is space in self for more bytes. Read more
Writes an unsigned 8 bit integer to self. Read more
Writes a signed 8 bit integer to self. Read more
Writes an unsigned 16 bit integer to self in big-endian byte order. Read more
Writes an unsigned 16 bit integer to self in little-endian byte order. Read more
Writes an unsigned 16 bit integer to self in native-endian byte order. Read more
Writes a signed 16 bit integer to self in big-endian byte order. Read more
Writes a signed 16 bit integer to self in little-endian byte order. Read more
Writes a signed 16 bit integer to self in native-endian byte order. Read more
Writes an unsigned 32 bit integer to self in big-endian byte order. Read more
Writes an unsigned 32 bit integer to self in little-endian byte order. Read more
Writes an unsigned 32 bit integer to self in native-endian byte order. Read more
Writes a signed 32 bit integer to self in big-endian byte order. Read more
Writes a signed 32 bit integer to self in little-endian byte order. Read more
Writes a signed 32 bit integer to self in native-endian byte order. Read more
Writes an unsigned 64 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 64 bit integer to self in little-endian byte order. Read more
Writes an unsigned 64 bit integer to self in native-endian byte order. Read more
Writes a signed 64 bit integer to self in the big-endian byte order. Read more
Writes a signed 64 bit integer to self in little-endian byte order. Read more
Writes a signed 64 bit integer to self in native-endian byte order. Read more
Writes an unsigned 128 bit integer to self in the big-endian byte order. Read more
Writes an unsigned 128 bit integer to self in little-endian byte order. Read more
Writes an unsigned 128 bit integer to self in native-endian byte order. Read more
Writes a signed 128 bit integer to self in the big-endian byte order. Read more
Writes a signed 128 bit integer to self in little-endian byte order. Read more
Writes a signed 128 bit integer to self in native-endian byte order. Read more
Writes an unsigned n-byte integer to self in big-endian byte order. Read more
Writes an unsigned n-byte integer to self in the little-endian byte order. Read more
Writes an unsigned n-byte integer to self in the native-endian byte order. Read more
Writes low nbytes of a signed integer to self in big-endian byte order. Read more
Writes low nbytes of a signed integer to self in little-endian byte order. Read more
Writes low nbytes of a signed integer to self in native-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order. Read more
Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order. Read more
Creates an adaptor which can write at most limit bytes to self. Read more
Available on crate feature std only.
Creates an adaptor which implements the Write trait for self. Read more
Creates an adapter which will chain this buffer with another. Read more
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
The resulting type after dereferencing.
Dereferences the value.
Mutably dereferences the value.
Deserialize this value from the given Serde deserializer. Read more
Executes the destructor for this type. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Extends a collection with the contents of an iterator. Read more
🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Converts to this type from the input type.
Creates a value from an iterator. Read more
Creates a value from an iterator. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
Formats the value using the given formatter.
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method tests for self and other values to be equal, and is used +by ==. Read more
This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
Serialize this value into the given Serde serializer. Read more
Formats the value using the given formatter.
Writes a string slice into this writer, returning whether the write +succeeded. Read more
Glue for usage of the write! macro with implementors of this trait. Read more
Writes a char into this writer, returning whether the write succeeded. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
\ No newline at end of file diff --git a/bytes/trait.Buf.html b/bytes/trait.Buf.html new file mode 100644 index 000000000..a4a70443a --- /dev/null +++ b/bytes/trait.Buf.html @@ -0,0 +1,619 @@ +Buf in bytes - Rust

Trait bytes::Buf

source ·
pub trait Buf {
+
Show 48 methods fn remaining(&self) -> usize; + fn chunk(&self) -> &[u8]; + fn advance(&mut self, cnt: usize); + + fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize { ... } + fn has_remaining(&self) -> bool { ... } + fn copy_to_slice(&mut self, dst: &mut [u8]) { ... } + fn get_u8(&mut self) -> u8 { ... } + fn get_i8(&mut self) -> i8 { ... } + fn get_u16(&mut self) -> u16 { ... } + fn get_u16_le(&mut self) -> u16 { ... } + fn get_u16_ne(&mut self) -> u16 { ... } + fn get_i16(&mut self) -> i16 { ... } + fn get_i16_le(&mut self) -> i16 { ... } + fn get_i16_ne(&mut self) -> i16 { ... } + fn get_u32(&mut self) -> u32 { ... } + fn get_u32_le(&mut self) -> u32 { ... } + fn get_u32_ne(&mut self) -> u32 { ... } + fn get_i32(&mut self) -> i32 { ... } + fn get_i32_le(&mut self) -> i32 { ... } + fn get_i32_ne(&mut self) -> i32 { ... } + fn get_u64(&mut self) -> u64 { ... } + fn get_u64_le(&mut self) -> u64 { ... } + fn get_u64_ne(&mut self) -> u64 { ... } + fn get_i64(&mut self) -> i64 { ... } + fn get_i64_le(&mut self) -> i64 { ... } + fn get_i64_ne(&mut self) -> i64 { ... } + fn get_u128(&mut self) -> u128 { ... } + fn get_u128_le(&mut self) -> u128 { ... } + fn get_u128_ne(&mut self) -> u128 { ... } + fn get_i128(&mut self) -> i128 { ... } + fn get_i128_le(&mut self) -> i128 { ... } + fn get_i128_ne(&mut self) -> i128 { ... } + fn get_uint(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_le(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_ne(&mut self, nbytes: usize) -> u64 { ... } + fn get_int(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_le(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_ne(&mut self, nbytes: usize) -> i64 { ... } + fn get_f32(&mut self) -> f32 { ... } + fn get_f32_le(&mut self) -> f32 { ... } + fn get_f32_ne(&mut self) -> f32 { ... } + fn get_f64(&mut self) -> f64 { ... } + fn get_f64_le(&mut self) -> f64 { ... } + fn get_f64_ne(&mut self) -> f64 { ... } + fn copy_to_bytes(&mut self, len: usize) -> Bytes { ... } + fn take(self, limit: usize) -> Take<Self>
    where
        Self: Sized
, + { ... } + fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
    where
        Self: Sized
, + { ... } + fn reader(self) -> Reader<Self>
    where
        Self: Sized
, + { ... } +
}
Expand description

Read bytes from a buffer.

+

A buffer stores bytes in memory such that read operations are 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. It can be thought of as an efficient Iterator for collections of +bytes.

+

The simplest Buf is a &[u8].

+ +
use bytes::Buf;
+
+let mut buf = &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 = [0; 8];
+buf.copy_to_slice(&mut rest);
+
+assert_eq!(&rest[..], &b"lo world"[..]);
+

Required Methods

Returns the number of bytes between the current position and the end of +the buffer.

+

This value is greater than or equal to the length of the slice returned +by chunk().

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.remaining(), 11);
+
+buf.get_u8();
+
+assert_eq!(buf.remaining(), 10);
+
Implementer notes
+

Implementations of remaining should ensure that the return value does +not change unless a call is made to advance or any other function that +is documented to change the Buf’s current position.

+

Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation).

+

This is a lower level function. Most operations are done with other +functions.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk() should return an +empty slice.

+

Advance the internal cursor of the Buf

+

The next call to chunk() will return a slice starting cnt bytes +further into the underlying buffer.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
Panics
+

This function may panic if cnt > self.remaining().

+
Implementer notes
+

It is recommended for implementations of advance to panic if cnt > self.remaining(). If the implementation does not panic, the call must +behave as if cnt == self.remaining().

+

A call with cnt == 0 should never panic and be a no-op.

+

Provided Methods

Available on crate feature std only.

Fills dst with potentially multiple slices starting at self’s +current position.

+

If the Buf is backed by disjoint slices of bytes, chunk_vectored enables +fetching more than one slice at once. dst is a slice of IoSlice +references, enabling the slice to be directly used with writev +without any further conversion. The sum of the lengths of all the +buffers in dst will be less than or equal to Buf::remaining().

+

The entries in dst will be overwritten, but the data contained by +the slices will not be modified. If chunk_vectored does not fill every +entry in dst, then dst is guaranteed to contain all remaining slices +in `self.

+

This is a lower level function. Most operations are done with other +functions.

+
Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk_vectored must return 0 +without mutating dst.

+

Implementations should also take care to properly handle being called +with dst being a zero length slice.

+

Returns true if there are any more bytes to consume

+

This is equivalent to self.remaining() != 0.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"a"[..];
+
+assert!(buf.has_remaining());
+
+buf.get_u8();
+
+assert!(!buf.has_remaining());
+

Copies bytes from self into dst.

+

The cursor is advanced by the number of bytes copied. self must have +enough remaining bytes to fill dst.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+let mut dst = [0; 5];
+
+buf.copy_to_slice(&mut dst);
+assert_eq!(&b"hello"[..], &dst);
+assert_eq!(6, buf.remaining());
+
Panics
+

This function panics if self.remaining() < dst.len().

+

Gets an unsigned 8 bit integer from self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_u8());
+
Panics
+

This function panics if there is no more remaining data in self.

+

Gets a signed 8 bit integer from self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_i8());
+
Panics
+

This function panics if there is no more remaining data in self.

+

Gets an unsigned 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_u16());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_u16_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_u16_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_i16());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_i16_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_i16_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in the big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in the little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_u32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_i32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_u64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_i64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets a signed 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_uint(3));
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_uint_le(3));
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an unsigned n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_uint_ne(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_int(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_int_le(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets a signed n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_int_ne(3));
+
Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
+assert_eq!(1.2f32, buf.get_f32());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
+assert_eq!(1.2f32, buf.get_f32_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\x99\x99\x9A hello",
+    false => b"\x9A\x99\x99\x3F hello",
+};
+assert_eq!(1.2f32, buf.get_f32_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
+assert_eq!(1.2f64, buf.get_f64());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
+assert_eq!(1.2f64, buf.get_f64_le());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello",
+    false => b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello",
+};
+assert_eq!(1.2f64, buf.get_f64_ne());
+
Panics
+

This function panics if there is not enough remaining data in self.

+

Consumes len bytes inside self and returns new instance of Bytes +with this data.

+

This function may be optimized by the underlying type to avoid actual +copies. For example, Bytes implementation will do a shallow copy +(ref-count increment).

+
Examples
+
use bytes::Buf;
+
+let bytes = (&b"hello world"[..]).copy_to_bytes(5);
+assert_eq!(&bytes[..], &b"hello"[..]);
+
Panics
+

This function panics if len > self.remaining().

+

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};
+
+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");
+

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;
+
+let mut chain = b"hello "[..].chain(&b"world"[..]);
+
+let full = chain.copy_to_bytes(11);
+assert_eq!(full.chunk(), b"hello world");
+
Available on crate feature std only.

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::{Bytes, Buf};
+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"[..]);
+

Implementations on Foreign Types

Available on crate feature std only.
Available on crate feature std only.

Implementors

\ No newline at end of file diff --git a/bytes/trait.BufMut.html b/bytes/trait.BufMut.html new file mode 100644 index 000000000..9ba3b1d75 --- /dev/null +++ b/bytes/trait.BufMut.html @@ -0,0 +1,732 @@ +BufMut in bytes - Rust

Trait bytes::BufMut

source ·
pub unsafe trait BufMut {
+
Show 48 methods fn remaining_mut(&self) -> usize; + unsafe fn advance_mut(&mut self, cnt: usize); + fn chunk_mut(&mut self) -> &mut UninitSlice; + + fn has_remaining_mut(&self) -> bool { ... } + fn put<T: Buf>(&mut self, src: T)
    where
        Self: Sized
, + { ... } + fn put_slice(&mut self, src: &[u8]) { ... } + fn put_bytes(&mut self, val: u8, cnt: usize) { ... } + fn put_u8(&mut self, n: u8) { ... } + fn put_i8(&mut self, n: i8) { ... } + fn put_u16(&mut self, n: u16) { ... } + fn put_u16_le(&mut self, n: u16) { ... } + fn put_u16_ne(&mut self, n: u16) { ... } + fn put_i16(&mut self, n: i16) { ... } + fn put_i16_le(&mut self, n: i16) { ... } + fn put_i16_ne(&mut self, n: i16) { ... } + fn put_u32(&mut self, n: u32) { ... } + fn put_u32_le(&mut self, n: u32) { ... } + fn put_u32_ne(&mut self, n: u32) { ... } + fn put_i32(&mut self, n: i32) { ... } + fn put_i32_le(&mut self, n: i32) { ... } + fn put_i32_ne(&mut self, n: i32) { ... } + fn put_u64(&mut self, n: u64) { ... } + fn put_u64_le(&mut self, n: u64) { ... } + fn put_u64_ne(&mut self, n: u64) { ... } + fn put_i64(&mut self, n: i64) { ... } + fn put_i64_le(&mut self, n: i64) { ... } + fn put_i64_ne(&mut self, n: i64) { ... } + fn put_u128(&mut self, n: u128) { ... } + fn put_u128_le(&mut self, n: u128) { ... } + fn put_u128_ne(&mut self, n: u128) { ... } + fn put_i128(&mut self, n: i128) { ... } + fn put_i128_le(&mut self, n: i128) { ... } + fn put_i128_ne(&mut self, n: i128) { ... } + fn put_uint(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_le(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_ne(&mut self, n: u64, nbytes: usize) { ... } + fn put_int(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_le(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_ne(&mut self, n: i64, nbytes: usize) { ... } + fn put_f32(&mut self, n: f32) { ... } + fn put_f32_le(&mut self, n: f32) { ... } + fn put_f32_ne(&mut self, n: f32) { ... } + fn put_f64(&mut self, n: f64) { ... } + fn put_f64_le(&mut self, n: f64) { ... } + fn put_f64_ne(&mut self, n: f64) { ... } + fn limit(self, limit: usize) -> Limit<Self>
    where
        Self: Sized
, + { ... } + fn writer(self) -> Writer<Self>
    where
        Self: Sized
, + { ... } + fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
    where
        Self: Sized
, + { ... } +
}
Expand description

A trait for values that provide sequential write access to bytes.

+

Write bytes to a buffer

+

A buffer stores bytes in memory such that write operations are infallible. +The underlying storage may or may not be in contiguous memory. A BufMut +value is a cursor into the buffer. Writing to BufMut advances the cursor +position.

+

The simplest BufMut is a Vec<u8>.

+ +
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put(&b"hello world"[..]);
+
+assert_eq!(buf, b"hello world");
+

Required Methods

Returns the number of bytes that can be written from the current +position until the end of the buffer is reached.

+

This value is greater than or equal to the length of the slice returned +by chunk_mut().

+

Writing to a BufMut may involve allocating more memory on the fly. +Implementations may fail before reaching the number of bytes indicated +by this method if they encounter an allocation failure.

+
Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 10];
+let mut buf = &mut dst[..];
+
+let original_remaining = buf.remaining_mut();
+buf.put(&b"hello"[..]);
+
+assert_eq!(original_remaining - 5, buf.remaining_mut());
+
Implementer notes
+

Implementations of remaining_mut should ensure that the return value +does not change unless a call is made to advance_mut or any other +function that is documented to change the BufMut’s current position.

+
Note
+

remaining_mut may return value smaller than actual available space.

+

Advance the internal cursor of the BufMut

+

The next call to chunk_mut will return a slice starting cnt bytes +further into the underlying buffer.

+
Safety
+

The caller must ensure that the next cnt bytes of chunk are +initialized.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+// Write some data
+buf.chunk_mut()[0..2].copy_from_slice(b"he");
+unsafe { buf.advance_mut(2) };
+
+// write more bytes
+buf.chunk_mut()[0..3].copy_from_slice(b"llo");
+
+unsafe { buf.advance_mut(3); }
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
Panics
+

This function may panic if cnt > self.remaining_mut().

+
Implementer notes
+

It is recommended for implementations of advance_mut to panic if +cnt > self.remaining_mut(). If the implementation does not panic, +the call must behave as if cnt == self.remaining_mut().

+

A call with cnt == 0 should never panic and be a no-op.

+

Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation).

+

This is a lower level function. Most operations are done with other +functions.

+

The returned byte slice may represent uninitialized memory.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+unsafe {
+    // MaybeUninit::as_mut_ptr
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'h');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'e');
+
+    buf.advance_mut(2);
+
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[2..].as_mut_ptr().write(b'o');
+
+    buf.advance_mut(3);
+}
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
Implementer notes
+

This function should never panic. chunk_mut should return an empty +slice if and only if remaining_mut() returns 0. In other words, +chunk_mut() returning an empty slice implies that remaining_mut() will +return 0 and remaining_mut() returning 0 implies that chunk_mut() will +return an empty slice.

+

This function may trigger an out-of-memory abort if it tries to allocate +memory and fails to do so.

+

Provided Methods

Returns true if there is space in self for more bytes.

+

This is equivalent to self.remaining_mut() != 0.

+
Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 5];
+let mut buf = &mut dst[..];
+
+assert!(buf.has_remaining_mut());
+
+buf.put(&b"hello"[..]);
+
+assert!(!buf.has_remaining_mut());
+

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put_u8(b'h');
+buf.put(&b"ello"[..]);
+buf.put(&b" world"[..]);
+
+assert_eq!(buf, b"hello world");
+
Panics
+

Panics if self does not have enough capacity to contain src.

+

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+

self must have enough remaining capacity to contain all of src.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_slice(b"hello");
+
+    assert_eq!(1, buf.remaining_mut());
+}
+
+assert_eq!(b"hello\0", &dst);
+

Put cnt bytes val into self.

+

Logically equivalent to calling self.put_u8(val) cnt times, but may work faster.

+

self must have at least cnt remaining capacity.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_bytes(b'a', 4);
+
+    assert_eq!(2, buf.remaining_mut());
+}
+
+assert_eq!(b"aaaa\0\0", &dst);
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 8 bit integer to self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u8(0x01);
+assert_eq!(buf, b"\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 8 bit integer to self.

+

The current position is advanced by 1.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i8(0x01);
+assert_eq!(buf, b"\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes a signed 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an unsigned n-byte integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint(0x010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an unsigned n-byte integer to self in the little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_le(0x010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an unsigned n-byte integer to self in the native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int(0x0504010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in little-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_le(0x0504010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes low nbytes of a signed integer to self in native-endian byte order.

+

The current position is advanced by nbytes.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32(1.2f32);
+assert_eq!(buf, b"\x3F\x99\x99\x9A");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_le(1.2f32);
+assert_eq!(buf, b"\x9A\x99\x99\x3F");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 4.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_ne(1.2f32);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\x99\x99\x9A");
+} else {
+    assert_eq!(buf, b"\x9A\x99\x99\x3F");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64(1.2f64);
+assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_le(1.2f64);
+assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 8.

+
Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_ne(1.2f64);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+} else {
+    assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+}
+
Panics
+

This function panics if there is not enough remaining capacity in +self.

+

Creates an adaptor which can write at most limit bytes to self.

+
Examples
+
use bytes::BufMut;
+
+let arr = &mut [0u8; 128][..];
+assert_eq!(arr.remaining_mut(), 128);
+
+let dst = arr.limit(10);
+assert_eq!(dst.remaining_mut(), 10);
+
Available on crate feature std only.

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;
+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"[..]);
+

Creates an adapter which will chain this buffer with another.

+

The returned BufMut instance will first write to all bytes from +self. Afterwards, it will write to next.

+
Examples
+
use bytes::BufMut;
+
+let mut a = [0u8; 5];
+let mut b = [0u8; 6];
+
+let mut chain = (&mut a[..]).chain_mut(&mut b[..]);
+
+chain.put_slice(b"hello world");
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b" world");
+

Implementations on Foreign Types

Implementors

\ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 000000000..d5d218da6 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["bytes"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 000000000..825784f4f --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Rustdoc help

Rustdoc help

Back
\ No newline at end of file diff --git a/implementors/bytes/buf/buf_impl/trait.Buf.js b/implementors/bytes/buf/buf_impl/trait.Buf.js new file mode 100644 index 000000000..90df62553 --- /dev/null +++ b/implementors/bytes/buf/buf_impl/trait.Buf.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/bytes/buf/buf_mut/trait.BufMut.js b/implementors/bytes/buf/buf_mut/trait.BufMut.js new file mode 100644 index 000000000..90df62553 --- /dev/null +++ b/implementors/bytes/buf/buf_mut/trait.BufMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/borrow/trait.Borrow.js b/implementors/core/borrow/trait.Borrow.js new file mode 100644 index 000000000..1ebef87da --- /dev/null +++ b/implementors/core/borrow/trait.Borrow.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Borrow<[u8]> for Bytes"],["impl Borrow<[u8]> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/borrow/trait.BorrowMut.js b/implementors/core/borrow/trait.BorrowMut.js new file mode 100644 index 000000000..cb60715ca --- /dev/null +++ b/implementors/core/borrow/trait.BorrowMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl BorrowMut<[u8]> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 000000000..679f3fb84 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Clone for Bytes"],["impl Clone for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Eq.js b/implementors/core/cmp/trait.Eq.js new file mode 100644 index 000000000..011a75db8 --- /dev/null +++ b/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Eq for Bytes"],["impl Eq for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Ord.js b/implementors/core/cmp/trait.Ord.js new file mode 100644 index 000000000..5af7ee3c6 --- /dev/null +++ b/implementors/core/cmp/trait.Ord.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Ord for Bytes"],["impl Ord for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialEq.js b/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 000000000..87eb2429f --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl PartialEq<Bytes> for Bytes"],["impl PartialEq<[u8]> for Bytes"],["impl PartialEq<Bytes> for [u8]"],["impl PartialEq<str> for Bytes"],["impl PartialEq<Bytes> for str"],["impl PartialEq<Vec<u8, Global>> for Bytes"],["impl PartialEq<Bytes> for Vec<u8>"],["impl PartialEq<String> for Bytes"],["impl PartialEq<Bytes> for String"],["impl PartialEq<Bytes> for &[u8]"],["impl PartialEq<Bytes> for &str"],["impl<'a, T: ?Sized> PartialEq<&'a T> for Byteswhere
    Bytes: PartialEq<T>,
"],["impl PartialEq<BytesMut> for BytesMut"],["impl PartialEq<[u8]> for BytesMut"],["impl PartialEq<BytesMut> for [u8]"],["impl PartialEq<str> for BytesMut"],["impl PartialEq<BytesMut> for str"],["impl PartialEq<Vec<u8, Global>> for BytesMut"],["impl PartialEq<BytesMut> for Vec<u8>"],["impl PartialEq<String> for BytesMut"],["impl PartialEq<BytesMut> for String"],["impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMutwhere
    BytesMut: PartialEq<T>,
"],["impl PartialEq<BytesMut> for &[u8]"],["impl PartialEq<BytesMut> for &str"],["impl PartialEq<BytesMut> for Bytes"],["impl PartialEq<Bytes> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialOrd.js b/implementors/core/cmp/trait.PartialOrd.js new file mode 100644 index 000000000..2abeeea26 --- /dev/null +++ b/implementors/core/cmp/trait.PartialOrd.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl PartialOrd<Bytes> for Bytes"],["impl PartialOrd<[u8]> for Bytes"],["impl PartialOrd<Bytes> for [u8]"],["impl PartialOrd<str> for Bytes"],["impl PartialOrd<Bytes> for str"],["impl PartialOrd<Vec<u8, Global>> for Bytes"],["impl PartialOrd<Bytes> for Vec<u8>"],["impl PartialOrd<String> for Bytes"],["impl PartialOrd<Bytes> for String"],["impl PartialOrd<Bytes> for &[u8]"],["impl PartialOrd<Bytes> for &str"],["impl<'a, T: ?Sized> PartialOrd<&'a T> for Byteswhere
    Bytes: PartialOrd<T>,
"],["impl PartialOrd<BytesMut> for BytesMut"],["impl PartialOrd<[u8]> for BytesMut"],["impl PartialOrd<BytesMut> for [u8]"],["impl PartialOrd<str> for BytesMut"],["impl PartialOrd<BytesMut> for str"],["impl PartialOrd<Vec<u8, Global>> for BytesMut"],["impl PartialOrd<BytesMut> for Vec<u8>"],["impl PartialOrd<String> for BytesMut"],["impl PartialOrd<BytesMut> for String"],["impl<'a, T: ?Sized> PartialOrd<&'a T> for BytesMutwhere
    BytesMut: PartialOrd<T>,
"],["impl PartialOrd<BytesMut> for &[u8]"],["impl PartialOrd<BytesMut> for &str"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsMut.js b/implementors/core/convert/trait.AsMut.js new file mode 100644 index 000000000..4ed670ad5 --- /dev/null +++ b/implementors/core/convert/trait.AsMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl AsMut<[u8]> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsRef.js b/implementors/core/convert/trait.AsRef.js new file mode 100644 index 000000000..6236898ca --- /dev/null +++ b/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl AsRef<[u8]> for Bytes"],["impl AsRef<[u8]> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.From.js b/implementors/core/convert/trait.From.js new file mode 100644 index 000000000..3bfd91945 --- /dev/null +++ b/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<'a> From<&'a mut [u8]> for &'a mut UninitSlice"],["impl<'a> From<&'a mut [MaybeUninit<u8>]> for &'a mut UninitSlice"],["impl From<&'static [u8]> for Bytes"],["impl From<&'static str> for Bytes"],["impl From<Vec<u8, Global>> for Bytes"],["impl From<Box<[u8], Global>> for Bytes"],["impl From<String> for Bytes"],["impl From<Bytes> for Vec<u8>"],["impl<'a> From<&'a [u8]> for BytesMut"],["impl<'a> From<&'a str> for BytesMut"],["impl From<BytesMut> for Bytes"],["impl From<BytesMut> for Vec<u8>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 000000000..353d698e3 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Default for Bytes"],["impl Default for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 000000000..8bae6f7c7 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T: Debug, U: Debug> Debug for Chain<T, U>"],["impl<T: Debug> Debug for IntoIter<T>"],["impl<T: Debug> Debug for Limit<T>"],["impl<B: Debug> Debug for Reader<B>"],["impl<T: Debug> Debug for Take<T>"],["impl Debug for UninitSlice"],["impl<B: Debug> Debug for Writer<B>"],["impl Debug for Bytes"],["impl Debug for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.LowerHex.js b/implementors/core/fmt/trait.LowerHex.js new file mode 100644 index 000000000..82337ac45 --- /dev/null +++ b/implementors/core/fmt/trait.LowerHex.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl LowerHex for Bytes"],["impl LowerHex for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.UpperHex.js b/implementors/core/fmt/trait.UpperHex.js new file mode 100644 index 000000000..651321602 --- /dev/null +++ b/implementors/core/fmt/trait.UpperHex.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl UpperHex for Bytes"],["impl UpperHex for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Write.js b/implementors/core/fmt/trait.Write.js new file mode 100644 index 000000000..94879765d --- /dev/null +++ b/implementors/core/fmt/trait.Write.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Write for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/hash/trait.Hash.js b/implementors/core/hash/trait.Hash.js new file mode 100644 index 000000000..a5cabd0d5 --- /dev/null +++ b/implementors/core/hash/trait.Hash.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Hash for Bytes"],["impl Hash for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/collect/trait.Extend.js b/implementors/core/iter/traits/collect/trait.Extend.js new file mode 100644 index 000000000..f5b17c1c6 --- /dev/null +++ b/implementors/core/iter/traits/collect/trait.Extend.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Extend<u8> for BytesMut"],["impl<'a> Extend<&'a u8> for BytesMut"],["impl Extend<Bytes> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/collect/trait.FromIterator.js b/implementors/core/iter/traits/collect/trait.FromIterator.js new file mode 100644 index 000000000..618b87b44 --- /dev/null +++ b/implementors/core/iter/traits/collect/trait.FromIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl FromIterator<u8> for Bytes"],["impl FromIterator<u8> for BytesMut"],["impl<'a> FromIterator<&'a u8> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/collect/trait.IntoIterator.js b/implementors/core/iter/traits/collect/trait.IntoIterator.js new file mode 100644 index 000000000..33fc8cdfa --- /dev/null +++ b/implementors/core/iter/traits/collect/trait.IntoIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> IntoIterator for Chain<T, U>where
    T: Buf,
    U: Buf,
"],["impl IntoIterator for Bytes"],["impl<'a> IntoIterator for &'a Bytes"],["impl IntoIterator for BytesMut"],["impl<'a> IntoIterator for &'a BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js b/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js new file mode 100644 index 000000000..805ad6be5 --- /dev/null +++ b/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T: Buf> ExactSizeIterator for IntoIter<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/iterator/trait.Iterator.js b/implementors/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 000000000..65d236088 --- /dev/null +++ b/implementors/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T: Buf> Iterator for IntoIter<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 000000000..de7dc7a90 --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> Freeze for Chain<T, U>where
    T: Freeze,
    U: Freeze,
",1,["bytes::buf::chain::Chain"]],["impl<T> Freeze for IntoIter<T>where
    T: Freeze,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> Freeze for Limit<T>where
    T: Freeze,
",1,["bytes::buf::limit::Limit"]],["impl<B> Freeze for Reader<B>where
    B: Freeze,
",1,["bytes::buf::reader::Reader"]],["impl<T> Freeze for Take<T>where
    T: Freeze,
",1,["bytes::buf::take::Take"]],["impl Freeze for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> Freeze for Writer<B>where
    B: Freeze,
",1,["bytes::buf::writer::Writer"]],["impl !Freeze for Bytes",1,["bytes::bytes::Bytes"]],["impl Freeze for BytesMut",1,["bytes::bytes_mut::BytesMut"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 000000000..8b4a86c96 --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> Send for Chain<T, U>where
    T: Send,
    U: Send,
",1,["bytes::buf::chain::Chain"]],["impl<T> Send for IntoIter<T>where
    T: Send,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> Send for Limit<T>where
    T: Send,
",1,["bytes::buf::limit::Limit"]],["impl<B> Send for Reader<B>where
    B: Send,
",1,["bytes::buf::reader::Reader"]],["impl<T> Send for Take<T>where
    T: Send,
",1,["bytes::buf::take::Take"]],["impl Send for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> Send for Writer<B>where
    B: Send,
",1,["bytes::buf::writer::Writer"]],["impl Send for Bytes"],["impl Send for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sized.js b/implementors/core/marker/trait.Sized.js new file mode 100644 index 000000000..ead86437c --- /dev/null +++ b/implementors/core/marker/trait.Sized.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl !Sized for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 000000000..7233b12d3 --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> Sync for Chain<T, U>where
    T: Sync,
    U: Sync,
",1,["bytes::buf::chain::Chain"]],["impl<T> Sync for IntoIter<T>where
    T: Sync,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> Sync for Limit<T>where
    T: Sync,
",1,["bytes::buf::limit::Limit"]],["impl<B> Sync for Reader<B>where
    B: Sync,
",1,["bytes::buf::reader::Reader"]],["impl<T> Sync for Take<T>where
    T: Sync,
",1,["bytes::buf::take::Take"]],["impl Sync for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> Sync for Writer<B>where
    B: Sync,
",1,["bytes::buf::writer::Writer"]],["impl Sync for Bytes"],["impl Sync for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 000000000..13e92368e --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> Unpin for Chain<T, U>where
    T: Unpin,
    U: Unpin,
",1,["bytes::buf::chain::Chain"]],["impl<T> Unpin for IntoIter<T>where
    T: Unpin,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> Unpin for Limit<T>where
    T: Unpin,
",1,["bytes::buf::limit::Limit"]],["impl<B> Unpin for Reader<B>where
    B: Unpin,
",1,["bytes::buf::reader::Reader"]],["impl<T> Unpin for Take<T>where
    T: Unpin,
",1,["bytes::buf::take::Take"]],["impl Unpin for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> Unpin for Writer<B>where
    B: Unpin,
",1,["bytes::buf::writer::Writer"]],["impl Unpin for Bytes",1,["bytes::bytes::Bytes"]],["impl Unpin for BytesMut",1,["bytes::bytes_mut::BytesMut"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/deref/trait.Deref.js b/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 000000000..f98cd02ce --- /dev/null +++ b/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Deref for Bytes"],["impl Deref for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/deref/trait.DerefMut.js b/implementors/core/ops/deref/trait.DerefMut.js new file mode 100644 index 000000000..ddb09ad2b --- /dev/null +++ b/implementors/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl DerefMut for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/drop/trait.Drop.js b/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 000000000..669f6e277 --- /dev/null +++ b/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Drop for Bytes"],["impl Drop for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.Index.js b/implementors/core/ops/index/trait.Index.js new file mode 100644 index 000000000..b7685fe05 --- /dev/null +++ b/implementors/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Index<Range<usize>> for UninitSlice"],["impl Index<RangeFrom<usize>> for UninitSlice"],["impl Index<RangeFull> for UninitSlice"],["impl Index<RangeInclusive<usize>> for UninitSlice"],["impl Index<RangeTo<usize>> for UninitSlice"],["impl Index<RangeToInclusive<usize>> for UninitSlice"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.IndexMut.js b/implementors/core/ops/index/trait.IndexMut.js new file mode 100644 index 000000000..91034dbad --- /dev/null +++ b/implementors/core/ops/index/trait.IndexMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl IndexMut<Range<usize>> for UninitSlice"],["impl IndexMut<RangeFrom<usize>> for UninitSlice"],["impl IndexMut<RangeFull> for UninitSlice"],["impl IndexMut<RangeInclusive<usize>> for UninitSlice"],["impl IndexMut<RangeTo<usize>> for UninitSlice"],["impl IndexMut<RangeToInclusive<usize>> for UninitSlice"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 000000000..9d83d5624 --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> RefUnwindSafe for Chain<T, U>where
    T: RefUnwindSafe,
    U: RefUnwindSafe,
",1,["bytes::buf::chain::Chain"]],["impl<T> RefUnwindSafe for IntoIter<T>where
    T: RefUnwindSafe,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> RefUnwindSafe for Limit<T>where
    T: RefUnwindSafe,
",1,["bytes::buf::limit::Limit"]],["impl<B> RefUnwindSafe for Reader<B>where
    B: RefUnwindSafe,
",1,["bytes::buf::reader::Reader"]],["impl<T> RefUnwindSafe for Take<T>where
    T: RefUnwindSafe,
",1,["bytes::buf::take::Take"]],["impl RefUnwindSafe for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> RefUnwindSafe for Writer<B>where
    B: RefUnwindSafe,
",1,["bytes::buf::writer::Writer"]],["impl RefUnwindSafe for Bytes",1,["bytes::bytes::Bytes"]],["impl RefUnwindSafe for BytesMut",1,["bytes::bytes_mut::BytesMut"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 000000000..df4399e14 --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<T, U> UnwindSafe for Chain<T, U>where
    T: UnwindSafe,
    U: UnwindSafe,
",1,["bytes::buf::chain::Chain"]],["impl<T> UnwindSafe for IntoIter<T>where
    T: UnwindSafe,
",1,["bytes::buf::iter::IntoIter"]],["impl<T> UnwindSafe for Limit<T>where
    T: UnwindSafe,
",1,["bytes::buf::limit::Limit"]],["impl<B> UnwindSafe for Reader<B>where
    B: UnwindSafe,
",1,["bytes::buf::reader::Reader"]],["impl<T> UnwindSafe for Take<T>where
    T: UnwindSafe,
",1,["bytes::buf::take::Take"]],["impl UnwindSafe for UninitSlice",1,["bytes::buf::uninit_slice::UninitSlice"]],["impl<B> UnwindSafe for Writer<B>where
    B: UnwindSafe,
",1,["bytes::buf::writer::Writer"]],["impl UnwindSafe for Bytes",1,["bytes::bytes::Bytes"]],["impl UnwindSafe for BytesMut",1,["bytes::bytes_mut::BytesMut"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/serde/de/trait.Deserialize.js b/implementors/serde/de/trait.Deserialize.js new file mode 100644 index 000000000..b811b16b6 --- /dev/null +++ b/implementors/serde/de/trait.Deserialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<'de> Deserialize<'de> for Bytes"],["impl<'de> Deserialize<'de> for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/serde/ser/trait.Serialize.js b/implementors/serde/ser/trait.Serialize.js new file mode 100644 index 000000000..e8a5f8264 --- /dev/null +++ b/implementors/serde/ser/trait.Serialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl Serialize for Bytes"],["impl Serialize for BytesMut"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/io/trait.BufRead.js b/implementors/std/io/trait.BufRead.js new file mode 100644 index 000000000..b18c214de --- /dev/null +++ b/implementors/std/io/trait.BufRead.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<B: Buf + Sized> BufRead for Reader<B>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/io/trait.Read.js b/implementors/std/io/trait.Read.js new file mode 100644 index 000000000..c5653d598 --- /dev/null +++ b/implementors/std/io/trait.Read.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<B: Buf + Sized> Read for Reader<B>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/io/trait.Write.js b/implementors/std/io/trait.Write.js new file mode 100644 index 000000000..1f57e9d99 --- /dev/null +++ b/implementors/std/io/trait.Write.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bytes":[["impl<B: BufMut + Sized> Write for Writer<B>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 000000000..b33414827 --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"bytes":{"doc":"Provides abstractions for working with bytes.","t":[8,8,3,3,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,0,11,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,8,8,3,3,3,3,3,3,3,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,11,11,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Buf","BufMut","Bytes","BytesMut","advance","advance","advance","advance_mut","advance_mut","as_mut","as_ref","as_ref","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","buf","capacity","chunk","chunk","chunk","chunk_mut","chunk_mut","clear","clear","clone","clone","clone_into","clone_into","cmp","cmp","copy_from_slice","copy_to_bytes","copy_to_bytes","default","default","deref","deref","deref_mut","deserialize","deserialize","drop","drop","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","extend","extend","extend","extend_from_slice","fmt","fmt","fmt","fmt","fmt","fmt","freeze","from","from","from","from","from","from","from","from","from","from","from_iter","from_iter","from_iter","from_static","hash","hash","into","into","into_iter","into_iter","into_iter","into_iter","is_empty","is_empty","is_unique","len","len","new","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","put","put_bytes","put_slice","remaining","remaining","remaining","remaining_mut","remaining_mut","reserve","resize","serialize","serialize","set_len","slice","slice_ref","spare_capacity_mut","split","split_off","split_off","split_to","split_to","to_owned","to_owned","truncate","truncate","try_from","try_from","try_into","try_into","type_id","type_id","unsplit","with_capacity","write_fmt","write_str","zeroed","Buf","BufMut","Chain","IntoIter","Limit","Reader","Take","UninitSlice","Writer","advance","advance","advance","advance_mut","advance_mut","advance_mut","as_mut_ptr","as_uninit_slice_mut","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","chain","chain","chain","chain_mut","chain_mut","chain_mut","chunk","chunk","chunk","chunk_mut","chunk_mut","chunk_mut","chunks_vectored","chunks_vectored","chunks_vectored","chunks_vectored","consume","copy_from_slice","copy_to_bytes","copy_to_bytes","copy_to_bytes","copy_to_bytes","copy_to_bytes","copy_to_slice","copy_to_slice","copy_to_slice","fill_buf","first_mut","first_ref","flush","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_raw_parts_mut","get_f32","get_f32","get_f32","get_f32_le","get_f32_le","get_f32_le","get_f32_ne","get_f32_ne","get_f32_ne","get_f64","get_f64","get_f64","get_f64_le","get_f64_le","get_f64_le","get_f64_ne","get_f64_ne","get_f64_ne","get_i128","get_i128","get_i128","get_i128_le","get_i128_le","get_i128_le","get_i128_ne","get_i128_ne","get_i128_ne","get_i16","get_i16","get_i16","get_i16_le","get_i16_le","get_i16_le","get_i16_ne","get_i16_ne","get_i16_ne","get_i32","get_i32","get_i32","get_i32_le","get_i32_le","get_i32_le","get_i32_ne","get_i32_ne","get_i32_ne","get_i64","get_i64","get_i64","get_i64_le","get_i64_le","get_i64_le","get_i64_ne","get_i64_ne","get_i64_ne","get_i8","get_i8","get_i8","get_int","get_int","get_int","get_int_le","get_int_le","get_int_le","get_int_ne","get_int_ne","get_int_ne","get_mut","get_mut","get_mut","get_mut","get_mut","get_ref","get_ref","get_ref","get_ref","get_ref","get_u128","get_u128","get_u128","get_u128_le","get_u128_le","get_u128_le","get_u128_ne","get_u128_ne","get_u128_ne","get_u16","get_u16","get_u16","get_u16_le","get_u16_le","get_u16_le","get_u16_ne","get_u16_ne","get_u16_ne","get_u32","get_u32","get_u32","get_u32_le","get_u32_le","get_u32_le","get_u32_ne","get_u32_ne","get_u32_ne","get_u64","get_u64","get_u64","get_u64_le","get_u64_le","get_u64_le","get_u64_ne","get_u64_ne","get_u64_ne","get_u8","get_u8","get_u8","get_uint","get_uint","get_uint","get_uint_le","get_uint_le","get_uint_le","get_uint_ne","get_uint_ne","get_uint_ne","has_remaining","has_remaining","has_remaining","has_remaining_mut","has_remaining_mut","has_remaining_mut","index","index","index","index","index","index","index_mut","index_mut","index_mut","index_mut","index_mut","index_mut","into","into","into","into","into","into","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_iter","into_iter","last_mut","last_ref","len","limit","limit","limit","limit","limit","new","new","next","put","put","put","put_bytes","put_bytes","put_bytes","put_f32","put_f32","put_f32","put_f32_le","put_f32_le","put_f32_le","put_f32_ne","put_f32_ne","put_f32_ne","put_f64","put_f64","put_f64","put_f64_le","put_f64_le","put_f64_le","put_f64_ne","put_f64_ne","put_f64_ne","put_i128","put_i128","put_i128","put_i128_le","put_i128_le","put_i128_le","put_i128_ne","put_i128_ne","put_i128_ne","put_i16","put_i16","put_i16","put_i16_le","put_i16_le","put_i16_le","put_i16_ne","put_i16_ne","put_i16_ne","put_i32","put_i32","put_i32","put_i32_le","put_i32_le","put_i32_le","put_i32_ne","put_i32_ne","put_i32_ne","put_i64","put_i64","put_i64","put_i64_le","put_i64_le","put_i64_le","put_i64_ne","put_i64_ne","put_i64_ne","put_i8","put_i8","put_i8","put_int","put_int","put_int","put_int_le","put_int_le","put_int_le","put_int_ne","put_int_ne","put_int_ne","put_slice","put_slice","put_slice","put_u128","put_u128","put_u128","put_u128_le","put_u128_le","put_u128_le","put_u128_ne","put_u128_ne","put_u128_ne","put_u16","put_u16","put_u16","put_u16_le","put_u16_le","put_u16_le","put_u16_ne","put_u16_ne","put_u16_ne","put_u32","put_u32","put_u32","put_u32_le","put_u32_le","put_u32_le","put_u32_ne","put_u32_ne","put_u32_ne","put_u64","put_u64","put_u64","put_u64_le","put_u64_le","put_u64_le","put_u64_ne","put_u64_ne","put_u64_ne","put_u8","put_u8","put_u8","put_uint","put_uint","put_uint","put_uint_le","put_uint_le","put_uint_le","put_uint_ne","put_uint_ne","put_uint_ne","read","reader","reader","reader","remaining","remaining","remaining","remaining_mut","remaining_mut","remaining_mut","set_limit","set_limit","size_hint","take","take","take","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","uninit","write","write_byte","writer","writer","writer"],"q":["bytes","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","bytes::buf","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["Read bytes from a buffer.","A trait for values that provide sequential write access to …","A cheaply cloneable and sliceable chunk of contiguous …","A unique reference to a contiguous slice of memory.","Advance the internal cursor of the Buf","","","Advance the internal cursor of the BufMut","","","","","","","","","","","","Utilities for working with buffers.","Returns the number of bytes the BytesMut can hold without …","Returns a slice starting at the current position and of …","","","Returns a mutable slice starting at the current BufMut …","","Clears the buffer, removing all data.","Clears the buffer, removing all data. Existing capacity is …","","","","","","","Creates Bytes instance from slice, by copying it.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Appends given bytes to this BytesMut.","","","","","","","Converts self into an immutable Bytes.","Returns the argument unchanged.","","","","","","","","","Returns the argument unchanged.","","","","Creates a new Bytes from a static slice.","","","Calls U::from(self).","Calls U::from(self).","","","","","Returns true if the Bytes has a length of 0.","Returns true if the BytesMut has a length of 0.","Returns true if this is the only reference to the data.","Returns the number of bytes contained in this Bytes.","Returns the number of bytes contained in this BytesMut.","Creates a new empty Bytes.","Creates a new BytesMut with default capacity.","","","","","","","","","","","","","","","","Returns the number of bytes between the current position …","","","Returns the number of bytes that can be written from the …","","Reserves capacity for at least additional more bytes to be …","Resizes the buffer so that len is equal to new_len.","","","Sets the length of the buffer.","Returns a slice of self for the provided range.","Returns a slice of self that is equivalent to the given …","Returns the remaining spare capacity of the buffer as a …","Removes the bytes from the current view, returning them in …","Splits the bytes into two at the given index.","Splits the bytes into two at the given index.","Splits the bytes into two at the given index.","Splits the buffer into two at the given index.","","","Shortens the buffer, keeping the first len bytes and …","Shortens the buffer, keeping the first len bytes and …","","","","","","","Absorbs a BytesMut that was previously split off.","Creates a new BytesMut with the specified capacity.","","","Creates a new BytesMut, which is initialized with zero.","Read bytes from a buffer.","A trait for values that provide sequential write access to …","A Chain sequences two buffers.","Iterator over the bytes contained by the buffer.","A BufMut adapter which limits the amount of bytes that can …","A Buf adapter which implements io::Read for the inner …","A Buf adapter which limits the bytes read from an …","Uninitialized byte slice.","A BufMut adapter which implements io::Write for the inner …","Advance the internal cursor of the Buf","","","Advance the internal cursor of the BufMut","","","Return a raw pointer to the slice’s buffer.","Return a &mut [MaybeUninit<u8>] to this slice’s buffer.","","","","","","","","","","","","","","","Creates an adaptor which will chain this buffer with …","Creates an adaptor which will chain this buffer with …","Creates an adaptor which will chain this buffer with …","Creates an adapter which will chain this buffer with …","Creates an adapter which will chain this buffer with …","Creates an adapter which will chain this buffer with …","Returns a slice starting at the current position and of …","","","Returns a mutable slice starting at the current BufMut …","","","Fills dst with potentially multiple slices starting at self…","Fills dst with potentially multiple slices starting at self…","Fills dst with potentially multiple slices starting at self…","","","Copies bytes from src into self.","Consumes len bytes inside self and returns new instance of …","Consumes len bytes inside self and returns new instance of …","Consumes len bytes inside self and returns new instance of …","","","Copies bytes from self into dst.","Copies bytes from self into dst.","Copies bytes from self into dst.","","Gets a mutable reference to the first underlying Buf.","Gets a reference to the first underlying Buf.","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create a &mut UninitSlice from a pointer and a length.","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 single-precision (4 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets an IEEE754 double-precision (8 bytes) floating point …","Gets a signed 128 bit integer from self in big-endian byte …","Gets a signed 128 bit integer from self in big-endian byte …","Gets a signed 128 bit integer from self in big-endian byte …","Gets a signed 128 bit integer from self in little-endian …","Gets a signed 128 bit integer from self in little-endian …","Gets a signed 128 bit integer from self in little-endian …","Gets a signed 128 bit integer from self in native-endian …","Gets a signed 128 bit integer from self in native-endian …","Gets a signed 128 bit integer from self in native-endian …","Gets a signed 16 bit integer from self in big-endian byte …","Gets a signed 16 bit integer from self in big-endian byte …","Gets a signed 16 bit integer from self in big-endian byte …","Gets a signed 16 bit integer from self in little-endian …","Gets a signed 16 bit integer from self in little-endian …","Gets a signed 16 bit integer from self in little-endian …","Gets a signed 16 bit integer from self in native-endian …","Gets a signed 16 bit integer from self in native-endian …","Gets a signed 16 bit integer from self in native-endian …","Gets a signed 32 bit integer from self in big-endian byte …","Gets a signed 32 bit integer from self in big-endian byte …","Gets a signed 32 bit integer from self in big-endian byte …","Gets a signed 32 bit integer from self in little-endian …","Gets a signed 32 bit integer from self in little-endian …","Gets a signed 32 bit integer from self in little-endian …","Gets a signed 32 bit integer from self in native-endian …","Gets a signed 32 bit integer from self in native-endian …","Gets a signed 32 bit integer from self in native-endian …","Gets a signed 64 bit integer from self in big-endian byte …","Gets a signed 64 bit integer from self in big-endian byte …","Gets a signed 64 bit integer from self in big-endian byte …","Gets a signed 64 bit integer from self in little-endian …","Gets a signed 64 bit integer from self in little-endian …","Gets a signed 64 bit integer from self in little-endian …","Gets a signed 64 bit integer from self in native-endian …","Gets a signed 64 bit integer from self in native-endian …","Gets a signed 64 bit integer from self in native-endian …","Gets a signed 8 bit integer from self.","Gets a signed 8 bit integer from self.","Gets a signed 8 bit integer from self.","Gets a signed n-byte integer from self in big-endian byte …","Gets a signed n-byte integer from self in big-endian byte …","Gets a signed n-byte integer from self in big-endian byte …","Gets a signed n-byte integer from self in little-endian …","Gets a signed n-byte integer from self in little-endian …","Gets a signed n-byte integer from self in little-endian …","Gets a signed n-byte integer from self in native-endian …","Gets a signed n-byte integer from self in native-endian …","Gets a signed n-byte integer from self in native-endian …","Gets a mutable reference to the underlying Buf.","Gets a mutable reference to the underlying BufMut.","Gets a mutable reference to the underlying Buf.","Gets a mutable reference to the underlying Buf.","Gets a mutable reference to the underlying BufMut.","Gets a reference to the underlying Buf.","Gets a reference to the underlying BufMut.","Gets a reference to the underlying Buf.","Gets a reference to the underlying Buf.","Gets a reference to the underlying BufMut.","Gets an unsigned 128 bit integer from self in big-endian …","Gets an unsigned 128 bit integer from self in big-endian …","Gets an unsigned 128 bit integer from self in big-endian …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 128 bit integer from self in …","Gets an unsigned 16 bit integer from self in big-endian …","Gets an unsigned 16 bit integer from self in big-endian …","Gets an unsigned 16 bit integer from self in big-endian …","Gets an unsigned 16 bit integer from self in little-endian …","Gets an unsigned 16 bit integer from self in little-endian …","Gets an unsigned 16 bit integer from self in little-endian …","Gets an unsigned 16 bit integer from self in native-endian …","Gets an unsigned 16 bit integer from self in native-endian …","Gets an unsigned 16 bit integer from self in native-endian …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in the …","Gets an unsigned 32 bit integer from self in native-endian …","Gets an unsigned 32 bit integer from self in native-endian …","Gets an unsigned 32 bit integer from self in native-endian …","Gets an unsigned 64 bit integer from self in big-endian …","Gets an unsigned 64 bit integer from self in big-endian …","Gets an unsigned 64 bit integer from self in big-endian …","Gets an unsigned 64 bit integer from self in little-endian …","Gets an unsigned 64 bit integer from self in little-endian …","Gets an unsigned 64 bit integer from self in little-endian …","Gets an unsigned 64 bit integer from self in native-endian …","Gets an unsigned 64 bit integer from self in native-endian …","Gets an unsigned 64 bit integer from self in native-endian …","Gets an unsigned 8 bit integer from self.","Gets an unsigned 8 bit integer from self.","Gets an unsigned 8 bit integer from self.","Gets an unsigned n-byte integer from self in big-endian …","Gets an unsigned n-byte integer from self in big-endian …","Gets an unsigned n-byte integer from self in big-endian …","Gets an unsigned n-byte integer from self in little-endian …","Gets an unsigned n-byte integer from self in little-endian …","Gets an unsigned n-byte integer from self in little-endian …","Gets an unsigned n-byte integer from self in native-endian …","Gets an unsigned n-byte integer from self in native-endian …","Gets an unsigned n-byte integer from self in native-endian …","Returns true if there are any more bytes to consume","Returns true if there are any more bytes to consume","Returns true if there are any more bytes to consume","Returns true if there is space in self for more bytes.","Returns true if there is space in self for more bytes.","Returns true if there is space in self for more bytes.","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Consumes this Chain, returning the underlying values.","Consumes this IntoIter, returning the underlying value.","Consumes this Limit, returning the underlying value.","Consumes this Reader, returning the underlying value.","Consumes this Take, returning the underlying value.","Consumes this Writer, returning the underlying value.","","","Gets a mutable reference to the last underlying Buf.","Gets a reference to the last underlying Buf.","Returns the number of bytes in the slice.","Creates an adaptor which can write at most limit bytes to …","Creates an adaptor which can write at most limit bytes to …","Creates an adaptor which can write at most limit bytes to …","Returns the maximum number of bytes that can be written","Returns the maximum number of bytes that can be read.","Creates a &mut UninitSlice wrapping a slice of initialised …","Creates an iterator over the bytes contained by the buffer.","","Transfer bytes into self from src and advance the cursor …","Transfer bytes into self from src and advance the cursor …","Transfer bytes into self from src and advance the cursor …","Put cnt bytes val into self.","Put cnt bytes val into self.","Put cnt bytes val into self.","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 single-precision (4 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes an IEEE754 double-precision (8 bytes) floating …","Writes a signed 128 bit integer to self in the big-endian …","Writes a signed 128 bit integer to self in the big-endian …","Writes a signed 128 bit integer to self in the big-endian …","Writes a signed 128 bit integer to self in little-endian …","Writes a signed 128 bit integer to self in little-endian …","Writes a signed 128 bit integer to self in little-endian …","Writes a signed 128 bit integer to self in native-endian …","Writes a signed 128 bit integer to self in native-endian …","Writes a signed 128 bit integer to self in native-endian …","Writes a signed 16 bit integer to self in big-endian byte …","Writes a signed 16 bit integer to self in big-endian byte …","Writes a signed 16 bit integer to self in big-endian byte …","Writes a signed 16 bit integer to self in little-endian …","Writes a signed 16 bit integer to self in little-endian …","Writes a signed 16 bit integer to self in little-endian …","Writes a signed 16 bit integer to self in native-endian …","Writes a signed 16 bit integer to self in native-endian …","Writes a signed 16 bit integer to self in native-endian …","Writes a signed 32 bit integer to self in big-endian byte …","Writes a signed 32 bit integer to self in big-endian byte …","Writes a signed 32 bit integer to self in big-endian byte …","Writes a signed 32 bit integer to self in little-endian …","Writes a signed 32 bit integer to self in little-endian …","Writes a signed 32 bit integer to self in little-endian …","Writes a signed 32 bit integer to self in native-endian …","Writes a signed 32 bit integer to self in native-endian …","Writes a signed 32 bit integer to self in native-endian …","Writes a signed 64 bit integer to self in the big-endian …","Writes a signed 64 bit integer to self in the big-endian …","Writes a signed 64 bit integer to self in the big-endian …","Writes a signed 64 bit integer to self in little-endian …","Writes a signed 64 bit integer to self in little-endian …","Writes a signed 64 bit integer to self in little-endian …","Writes a signed 64 bit integer to self in native-endian …","Writes a signed 64 bit integer to self in native-endian …","Writes a signed 64 bit integer to self in native-endian …","Writes a signed 8 bit integer to self.","Writes a signed 8 bit integer to self.","Writes a signed 8 bit integer to self.","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Writes low nbytes of a signed integer to self in …","Transfer bytes into self from src and advance the cursor …","Transfer bytes into self from src and advance the cursor …","Transfer bytes into self from src and advance the cursor …","Writes an unsigned 128 bit integer to self in the …","Writes an unsigned 128 bit integer to self in the …","Writes an unsigned 128 bit integer to self in the …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 128 bit integer to self in …","Writes an unsigned 16 bit integer to self in big-endian …","Writes an unsigned 16 bit integer to self in big-endian …","Writes an unsigned 16 bit integer to self in big-endian …","Writes an unsigned 16 bit integer to self in little-endian …","Writes an unsigned 16 bit integer to self in little-endian …","Writes an unsigned 16 bit integer to self in little-endian …","Writes an unsigned 16 bit integer to self in native-endian …","Writes an unsigned 16 bit integer to self in native-endian …","Writes an unsigned 16 bit integer to self in native-endian …","Writes an unsigned 32 bit integer to self in big-endian …","Writes an unsigned 32 bit integer to self in big-endian …","Writes an unsigned 32 bit integer to self in big-endian …","Writes an unsigned 32 bit integer to self in little-endian …","Writes an unsigned 32 bit integer to self in little-endian …","Writes an unsigned 32 bit integer to self in little-endian …","Writes an unsigned 32 bit integer to self in native-endian …","Writes an unsigned 32 bit integer to self in native-endian …","Writes an unsigned 32 bit integer to self in native-endian …","Writes an unsigned 64 bit integer to self in the …","Writes an unsigned 64 bit integer to self in the …","Writes an unsigned 64 bit integer to self in the …","Writes an unsigned 64 bit integer to self in little-endian …","Writes an unsigned 64 bit integer to self in little-endian …","Writes an unsigned 64 bit integer to self in little-endian …","Writes an unsigned 64 bit integer to self in native-endian …","Writes an unsigned 64 bit integer to self in native-endian …","Writes an unsigned 64 bit integer to self in native-endian …","Writes an unsigned 8 bit integer to self.","Writes an unsigned 8 bit integer to self.","Writes an unsigned 8 bit integer to self.","Writes an unsigned n-byte integer to self in big-endian …","Writes an unsigned n-byte integer to self in big-endian …","Writes an unsigned n-byte integer to self in big-endian …","Writes an unsigned n-byte integer to self in the …","Writes an unsigned n-byte integer to self in the …","Writes an unsigned n-byte integer to self in the …","Writes an unsigned n-byte integer to self in the …","Writes an unsigned n-byte integer to self in the …","Writes an unsigned n-byte integer to self in the …","","Creates an adaptor which implements the Read trait for self…","Creates an adaptor which implements the Read trait for self…","Creates an adaptor which implements the Read trait for self…","Returns the number of bytes between the current position …","","","Returns the number of bytes that can be written from the …","","","Sets the maximum number of bytes that can be written.","Sets the maximum number of bytes that can be read.","","Creates an adaptor which will read at most limit bytes …","Creates an adaptor which will read at most limit bytes …","Creates an adaptor which will read at most limit bytes …","","","","","","","","","","","","","","","","","","","","Creates a &mut UninitSlice wrapping a slice of …","","Write a single byte at the specified offset.","Creates an adaptor which implements the Write trait for …","Creates an adaptor which implements the Write trait for …","Creates an adaptor which implements the Write trait for …"],"i":[0,0,0,0,17,2,3,23,3,3,2,3,2,2,3,3,2,3,3,0,3,17,2,3,23,3,2,3,2,3,2,3,2,3,2,2,3,2,3,2,3,3,2,3,2,3,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,2,2,2,2,2,2,2,3,3,3,2,3,3,2,2,3,2,3,2,2,3,3,2,3,2,2,3,2,3,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,17,2,3,23,3,3,3,2,3,3,2,2,3,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,17,21,22,23,21,24,4,4,4,21,30,24,26,22,28,4,21,30,24,26,22,28,17,17,17,23,23,23,17,21,22,23,21,24,17,17,17,21,26,4,17,17,17,21,22,17,17,17,26,21,21,28,4,21,30,24,26,22,28,4,4,21,30,24,26,22,28,4,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,30,24,26,22,28,30,24,26,22,28,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,23,23,23,4,4,4,4,4,4,4,4,4,4,4,4,21,30,24,26,22,28,21,30,24,26,22,28,21,30,21,21,4,23,23,23,24,22,4,30,30,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,26,17,17,17,17,21,22,23,21,24,24,22,30,17,17,17,21,30,24,26,22,28,21,30,24,26,22,28,4,21,30,24,26,22,28,4,28,4,23,23,23],"f":[0,0,0,0,[1],[[2,1]],[[3,1]],[1],[[3,1]],[3],[2],[3],[2],[[]],[3],[[]],[[]],[3],[[]],0,[3,1],[[]],[2],[3],[[],4],[3,4],[2],[3],[2,2],[3,3],[[]],[[]],[[2,2],5],[[3,3],5],[[],2],[[2,1],2],[[3,1],2],[[],2],[[],3],[2],[3],[3],[[],[[6,[2]]]],[[],[[6,[3]]]],[2],[3],[[2,7],8],[[2,2],8],[2,8],[[2,9],8],[[2,3],8],[[2,10],8],[2,8],[[3,2],8],[[3,10],8],[3,8],[3,8],[[3,9],8],[[3,3],8],[[3,7],8],[3],[3],[3],[3],[[2,11],12],[[2,11],12],[[2,11],12],[[3,11],12],[[3,11],12],[[3,11],12],[3,2],[[]],[10,2],[13,2],[3,2],[[[7,[14]]],2],[9,2],[[],2],[9,3],[[],3],[[]],[15,2],[15,3],[15,3],[[],2],[2],[3],[[]],[[]],[2],[2],[3],[3],[2,8],[3,8],[2,8],[2,1],[3,1],[[],2],[[],3],[2,[[16,[5]]]],[[2,10],[[16,[5]]]],[[2,7],[[16,[5]]]],[[2,9],[[16,[5]]]],[2,[[16,[5]]]],[[2,2],[[16,[5]]]],[3,[[16,[5]]]],[3,[[16,[5]]]],[[3,10],[[16,[5]]]],[[3,7],[[16,[5]]]],[[3,9],[[16,[5]]]],[[3,3],[[16,[5]]]],[[3,17]],[[3,14,1]],[3],[[],1],[2,1],[3,1],[[],1],[3,1],[[3,1]],[[3,1,14]],[2,6],[3,6],[[3,1]],[[2,[18,[1]]],2],[2,2],[3],[3,3],[[2,1],2],[[3,1],3],[[2,1],2],[[3,1],3],[[]],[[]],[[2,1]],[[3,1]],[[],6],[[],6],[[],6],[[],6],[[],19],[[],19],[[3,3]],[1,3],[[3,20],12],[[3,9],12],[1,3],0,0,0,0,0,0,0,0,0,[1],[[21,1]],[[[22,[17]],1]],[1],[[21,1]],[[[24,[23]],1]],[4,14],[4],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[17,[[21,[17]]]],[17,[[21,[17]]]],[17,[[21,[17]]]],[23,[[21,[23]]]],[23,[[21,[23]]]],[23,[[21,[23]]]],[[]],[21],[[[22,[17]]]],[[],4],[21,4],[[[24,[23]]],4],[[],1],[[],1],[[],1],[21,1],[[[26,[[0,[17,25]]]],1]],[4],[1,2],[1,2],[1,2],[[21,1],2],[[[22,[17]],1],2],[[]],[[]],[[]],[[[26,[[0,[17,25]]]]],27],[21],[21],[[[28,[[0,[23,25]]]]],27],[[4,11],12],[[[21,[29,29]],11],12],[[[30,[29]],11],12],[[[24,[29]],11],12],[[[26,[29]],11],12],[[[22,[29]],11],12],[[[28,[29]],11],12],[[],4],[[],4],[[]],[[]],[[]],[[]],[[]],[[]],[[14,1],4],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],33],[[],34],[[],34],[[],34],[[],34],[[],34],[[],34],[[],34],[[],34],[[],34],[[],35],[[],35],[[],35],[[],35],[[],35],[[],35],[[],35],[[],35],[[],35],[[],36],[[],36],[[],36],[[],36],[[],36],[[],36],[[],36],[[],36],[[],36],[[],37],[[],37],[[],37],[1,36],[1,36],[1,36],[1,36],[1,36],[1,36],[1,36],[1,36],[1,36],[30],[24],[[[26,[17]]]],[22],[[[28,[23]]]],[30],[24],[[[26,[17]]]],[22],[[[28,[23]]]],[[],38],[[],38],[[],38],[[],38],[[],38],[[],38],[[],38],[[],38],[[],38],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],39],[[],40],[[],40],[[],40],[[],40],[[],40],[[],40],[[],40],[[],40],[[],40],[[],41],[[],41],[[],41],[[],41],[[],41],[[],41],[[],41],[[],41],[[],41],[[],14],[[],14],[[],14],[1,41],[1,41],[1,41],[1,41],[1,41],[1,41],[1,41],[1,41],[1,41],[[],8],[[],8],[[],8],[[],8],[[],8],[[],8],[[4,[42,[1]]],4],[[4,[43,[1]]],4],[[4,[44,[1]]],4],[[4,45],4],[[4,[46,[1]]],4],[[4,[47,[1]]],4],[[4,[44,[1]]],4],[[4,[43,[1]]],4],[[4,[47,[1]]],4],[[4,[42,[1]]],4],[[4,45],4],[[4,[46,[1]]],4],[[]],[[]],[[]],[[]],[[]],[[]],[21],[30],[24],[[[26,[17]]],17],[22],[[[28,[23]]],23],[21],[[]],[21],[21],[4,1],[1,24],[1,24],[1,24],[24,1],[22,1],[[],4],[[],30],[[[30,[17]]],[[16,[14]]]],[17],[17],[17],[[14,1]],[[14,1]],[[14,1]],[31],[31],[31],[31],[31],[31],[31],[31],[31],[32],[32],[32],[32],[32],[32],[32],[32],[32],[33],[33],[33],[33],[33],[33],[33],[33],[33],[34],[34],[34],[34],[34],[34],[34],[34],[34],[35],[35],[35],[35],[35],[35],[35],[35],[35],[36],[36],[36],[36],[36],[36],[36],[36],[36],[37],[37],[37],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[36,1]],[[]],[[]],[[]],[38],[38],[38],[38],[38],[38],[38],[38],[38],[39],[39],[39],[39],[39],[39],[39],[39],[39],[40],[40],[40],[40],[40],[40],[40],[40],[40],[41],[41],[41],[41],[41],[41],[41],[41],[41],[14],[14],[14],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[41,1]],[[[26,[[0,[17,25]]]]],[[27,[1]]]],[[],26],[[],26],[[],26],[[],1],[21,1],[[[22,[17]]],1],[[],1],[21,1],[[[24,[23]]],1],[[24,1]],[[22,1]],[[[30,[17]]]],[1,22],[1,22],[1,22],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],6],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],19],[[],4],[[[28,[[0,[23,25]]]]],[[27,[1]]]],[[4,1,14]],[[],28],[[],28],[[],28]],"p":[[15,"usize"],[3,"Bytes"],[3,"BytesMut"],[3,"UninitSlice"],[4,"Ordering"],[4,"Result"],[3,"Vec"],[15,"bool"],[15,"str"],[3,"String"],[3,"Formatter"],[6,"Result"],[3,"Box"],[15,"u8"],[8,"IntoIterator"],[4,"Option"],[8,"Buf"],[8,"RangeBounds"],[3,"TypeId"],[3,"Arguments"],[3,"Chain"],[3,"Take"],[8,"BufMut"],[3,"Limit"],[8,"Sized"],[3,"Reader"],[6,"Result"],[3,"Writer"],[8,"Debug"],[3,"IntoIter"],[15,"f32"],[15,"f64"],[15,"i128"],[15,"i16"],[15,"i32"],[15,"i64"],[15,"i8"],[15,"u128"],[15,"u16"],[15,"u32"],[15,"u64"],[3,"RangeInclusive"],[3,"RangeTo"],[3,"RangeFrom"],[3,"RangeFull"],[3,"Range"],[3,"RangeToInclusive"]],"a":{"bytes":[21,185],"bytes_mut":[24,188]}}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/settings.html b/settings.html new file mode 100644 index 000000000..21db84e03 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/source-files.js b/source-files.js new file mode 100644 index 000000000..8c3d4ec04 --- /dev/null +++ b/source-files.js @@ -0,0 +1,4 @@ +var sourcesIndex = JSON.parse('{\ +"bytes":["",[["buf",[],["buf_impl.rs","buf_mut.rs","chain.rs","iter.rs","limit.rs","mod.rs","reader.rs","take.rs","uninit_slice.rs","vec_deque.rs","writer.rs"]],["fmt",[],["debug.rs","hex.rs","mod.rs"]]],["bytes.rs","bytes_mut.rs","lib.rs","loom.rs","serde.rs"]]\ +}'); +createSourceSidebar(); diff --git a/src/bytes/buf/buf_impl.rs.html b/src/bytes/buf/buf_impl.rs.html new file mode 100644 index 000000000..55d225c11 --- /dev/null +++ b/src/bytes/buf/buf_impl.rs.html @@ -0,0 +1,2930 @@ +buf_impl.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+
#[cfg(feature = "std")]
+use crate::buf::{reader, Reader};
+use crate::buf::{take, Chain, Take};
+#[cfg(feature = "std")]
+use crate::{min_u64_usize, saturating_sub_usize_u64};
+use crate::{panic_advance, panic_does_not_fit};
+
+#[cfg(feature = "std")]
+use std::io::IoSlice;
+
+use alloc::boxed::Box;
+
+macro_rules! buf_get_impl {
+    ($this:ident, $typ:tt::$conv:tt) => {{
+        const SIZE: usize = core::mem::size_of::<$typ>();
+
+        if $this.remaining() < SIZE {
+            panic_advance(SIZE, $this.remaining());
+        }
+
+        // try to convert directly from the bytes
+        // this Option<ret> trick is to avoid keeping a borrow on self
+        // when advance() is called (mut borrow) and to call bytes() only once
+        let ret = $this
+            .chunk()
+            .get(..SIZE)
+            .map(|src| unsafe { $typ::$conv(*(src as *const _ as *const [_; SIZE])) });
+
+        if let Some(ret) = ret {
+            // if the direct conversion was possible, advance and return
+            $this.advance(SIZE);
+            return ret;
+        } else {
+            // if not we copy the bytes in a temp buffer then convert
+            let mut buf = [0; SIZE];
+            $this.copy_to_slice(&mut buf); // (do the advance)
+            return $typ::$conv(buf);
+        }
+    }};
+    (le => $this:ident, $typ:tt, $len_to_read:expr) => {{
+        const SIZE: usize = core::mem::size_of::<$typ>();
+
+        // The same trick as above does not improve the best case speed.
+        // It seems to be linked to the way the method is optimised by the compiler
+        let mut buf = [0; SIZE];
+
+        let subslice = match buf.get_mut(..$len_to_read) {
+            Some(subslice) => subslice,
+            None => panic_does_not_fit(SIZE, $len_to_read),
+        };
+
+        $this.copy_to_slice(subslice);
+        return $typ::from_le_bytes(buf);
+    }};
+    (be => $this:ident, $typ:tt, $len_to_read:expr) => {{
+        const SIZE: usize = core::mem::size_of::<$typ>();
+
+        let slice_at = match SIZE.checked_sub($len_to_read) {
+            Some(slice_at) => slice_at,
+            None => panic_does_not_fit(SIZE, $len_to_read),
+        };
+
+        let mut buf = [0; SIZE];
+        $this.copy_to_slice(&mut buf[slice_at..]);
+        return $typ::from_be_bytes(buf);
+    }};
+}
+
+/// Read bytes from a buffer.
+///
+/// A buffer stores bytes in memory such that read operations are 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. It can be thought of as an efficient `Iterator` for collections of
+/// bytes.
+///
+/// The simplest `Buf` is a `&[u8]`.
+///
+/// ```
+/// use bytes::Buf;
+///
+/// let mut buf = &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 = [0; 8];
+/// buf.copy_to_slice(&mut rest);
+///
+/// assert_eq!(&rest[..], &b"lo world"[..]);
+/// ```
+pub trait Buf {
+    /// Returns the number of bytes between the current position and the end of
+    /// the buffer.
+    ///
+    /// This value is greater than or equal to the length of the slice returned
+    /// by `chunk()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"hello world"[..];
+    ///
+    /// assert_eq!(buf.remaining(), 11);
+    ///
+    /// buf.get_u8();
+    ///
+    /// assert_eq!(buf.remaining(), 10);
+    /// ```
+    ///
+    /// # Implementer notes
+    ///
+    /// Implementations of `remaining` should ensure that the return value does
+    /// not change unless a call is made to `advance` or any other function that
+    /// is documented to change the `Buf`'s current position.
+    fn remaining(&self) -> usize;
+
+    /// Returns a slice starting at the current position and of length between 0
+    /// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows
+    /// non-continuous internal representation).
+    ///
+    /// This is a lower level function. Most operations are done with other
+    /// functions.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"hello world"[..];
+    ///
+    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
+    ///
+    /// buf.advance(6);
+    ///
+    /// assert_eq!(buf.chunk(), &b"world"[..]);
+    /// ```
+    ///
+    /// # Implementer notes
+    ///
+    /// This function should never panic. Once the end of the buffer is reached,
+    /// i.e., `Buf::remaining` returns 0, calls to `chunk()` should return an
+    /// empty slice.
+    // The `chunk` method was previously called `bytes`. This alias makes the rename
+    // more easily discoverable.
+    #[cfg_attr(docsrs, doc(alias = "bytes"))]
+    fn chunk(&self) -> &[u8];
+
+    /// Fills `dst` with potentially multiple slices starting at `self`'s
+    /// current position.
+    ///
+    /// If the `Buf` is backed by disjoint slices of bytes, `chunk_vectored` enables
+    /// fetching more than one slice at once. `dst` is a slice of `IoSlice`
+    /// references, enabling the slice to be directly used with [`writev`]
+    /// without any further conversion. The sum of the lengths of all the
+    /// buffers in `dst` will be less than or equal to `Buf::remaining()`.
+    ///
+    /// The entries in `dst` will be overwritten, but the data **contained** by
+    /// the slices **will not** be modified. If `chunk_vectored` does not fill every
+    /// entry in `dst`, then `dst` is guaranteed to contain all remaining slices
+    /// in `self.
+    ///
+    /// This is a lower level function. Most operations are done with other
+    /// functions.
+    ///
+    /// # Implementer notes
+    ///
+    /// This function should never panic. Once the end of the buffer is reached,
+    /// i.e., `Buf::remaining` returns 0, calls to `chunk_vectored` must return 0
+    /// without mutating `dst`.
+    ///
+    /// Implementations should also take care to properly handle being called
+    /// with `dst` being a zero length slice.
+    ///
+    /// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html
+    #[cfg(feature = "std")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
+        if dst.is_empty() {
+            return 0;
+        }
+
+        if self.has_remaining() {
+            dst[0] = IoSlice::new(self.chunk());
+            1
+        } else {
+            0
+        }
+    }
+
+    /// Advance the internal cursor of the Buf
+    ///
+    /// The next call to `chunk()` will return a slice starting `cnt` bytes
+    /// further into the underlying buffer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"hello world"[..];
+    ///
+    /// assert_eq!(buf.chunk(), &b"hello world"[..]);
+    ///
+    /// buf.advance(6);
+    ///
+    /// assert_eq!(buf.chunk(), &b"world"[..]);
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function **may** panic if `cnt > self.remaining()`.
+    ///
+    /// # Implementer notes
+    ///
+    /// It is recommended for implementations of `advance` to panic if `cnt >
+    /// self.remaining()`. If the implementation does not panic, the call must
+    /// behave as if `cnt == self.remaining()`.
+    ///
+    /// A call with `cnt == 0` should never panic and be a no-op.
+    fn advance(&mut self, cnt: usize);
+
+    /// Returns true if there are any more bytes to consume
+    ///
+    /// This is equivalent to `self.remaining() != 0`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"a"[..];
+    ///
+    /// assert!(buf.has_remaining());
+    ///
+    /// buf.get_u8();
+    ///
+    /// assert!(!buf.has_remaining());
+    /// ```
+    fn has_remaining(&self) -> bool {
+        self.remaining() > 0
+    }
+
+    /// Copies bytes from `self` into `dst`.
+    ///
+    /// The cursor is advanced by the number of bytes copied. `self` must have
+    /// enough remaining bytes to fill `dst`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"hello world"[..];
+    /// let mut dst = [0; 5];
+    ///
+    /// buf.copy_to_slice(&mut dst);
+    /// assert_eq!(&b"hello"[..], &dst);
+    /// assert_eq!(6, buf.remaining());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `self.remaining() < dst.len()`.
+    fn copy_to_slice(&mut self, mut dst: &mut [u8]) {
+        if self.remaining() < dst.len() {
+            panic_advance(dst.len(), self.remaining());
+        }
+
+        while !dst.is_empty() {
+            let src = self.chunk();
+            let cnt = usize::min(src.len(), dst.len());
+
+            dst[..cnt].copy_from_slice(&src[..cnt]);
+            dst = &mut dst[cnt..];
+
+            self.advance(cnt);
+        }
+    }
+
+    /// Gets an unsigned 8 bit integer from `self`.
+    ///
+    /// The current position is advanced by 1.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08 hello"[..];
+    /// assert_eq!(8, buf.get_u8());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is no more remaining data in `self`.
+    fn get_u8(&mut self) -> u8 {
+        if self.remaining() < 1 {
+            panic_advance(1, 0);
+        }
+        let ret = self.chunk()[0];
+        self.advance(1);
+        ret
+    }
+
+    /// Gets a signed 8 bit integer from `self`.
+    ///
+    /// The current position is advanced by 1.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08 hello"[..];
+    /// assert_eq!(8, buf.get_i8());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is no more remaining data in `self`.
+    fn get_i8(&mut self) -> i8 {
+        if self.remaining() < 1 {
+            panic_advance(1, 0);
+        }
+        let ret = self.chunk()[0] as i8;
+        self.advance(1);
+        ret
+    }
+
+    /// Gets an unsigned 16 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x09 hello"[..];
+    /// assert_eq!(0x0809, buf.get_u16());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u16(&mut self) -> u16 {
+        buf_get_impl!(self, u16::from_be_bytes);
+    }
+
+    /// Gets an unsigned 16 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x09\x08 hello"[..];
+    /// assert_eq!(0x0809, buf.get_u16_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u16_le(&mut self) -> u16 {
+        buf_get_impl!(self, u16::from_le_bytes);
+    }
+
+    /// Gets an unsigned 16 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x08\x09 hello",
+    ///     false => b"\x09\x08 hello",
+    /// };
+    /// assert_eq!(0x0809, buf.get_u16_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u16_ne(&mut self) -> u16 {
+        buf_get_impl!(self, u16::from_ne_bytes);
+    }
+
+    /// Gets a signed 16 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x09 hello"[..];
+    /// assert_eq!(0x0809, buf.get_i16());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i16(&mut self) -> i16 {
+        buf_get_impl!(self, i16::from_be_bytes);
+    }
+
+    /// Gets a signed 16 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x09\x08 hello"[..];
+    /// assert_eq!(0x0809, buf.get_i16_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i16_le(&mut self) -> i16 {
+        buf_get_impl!(self, i16::from_le_bytes);
+    }
+
+    /// Gets a signed 16 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x08\x09 hello",
+    ///     false => b"\x09\x08 hello",
+    /// };
+    /// assert_eq!(0x0809, buf.get_i16_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i16_ne(&mut self) -> i16 {
+        buf_get_impl!(self, i16::from_ne_bytes);
+    }
+
+    /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+    /// assert_eq!(0x0809A0A1, buf.get_u32());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u32(&mut self) -> u32 {
+        buf_get_impl!(self, u32::from_be_bytes);
+    }
+
+    /// Gets an unsigned 32 bit integer from `self` in the little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+    /// assert_eq!(0x0809A0A1, buf.get_u32_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u32_le(&mut self) -> u32 {
+        buf_get_impl!(self, u32::from_le_bytes);
+    }
+
+    /// Gets an unsigned 32 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x08\x09\xA0\xA1 hello",
+    ///     false => b"\xA1\xA0\x09\x08 hello",
+    /// };
+    /// assert_eq!(0x0809A0A1, buf.get_u32_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u32_ne(&mut self) -> u32 {
+        buf_get_impl!(self, u32::from_ne_bytes);
+    }
+
+    /// Gets a signed 32 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+    /// assert_eq!(0x0809A0A1, buf.get_i32());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i32(&mut self) -> i32 {
+        buf_get_impl!(self, i32::from_be_bytes);
+    }
+
+    /// Gets a signed 32 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+    /// assert_eq!(0x0809A0A1, buf.get_i32_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i32_le(&mut self) -> i32 {
+        buf_get_impl!(self, i32::from_le_bytes);
+    }
+
+    /// Gets a signed 32 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x08\x09\xA0\xA1 hello",
+    ///     false => b"\xA1\xA0\x09\x08 hello",
+    /// };
+    /// assert_eq!(0x0809A0A1, buf.get_i32_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i32_ne(&mut self) -> i32 {
+        buf_get_impl!(self, i32::from_ne_bytes);
+    }
+
+    /// Gets an unsigned 64 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+    /// assert_eq!(0x0102030405060708, buf.get_u64());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u64(&mut self) -> u64 {
+        buf_get_impl!(self, u64::from_be_bytes);
+    }
+
+    /// Gets an unsigned 64 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x0102030405060708, buf.get_u64_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u64_le(&mut self) -> u64 {
+        buf_get_impl!(self, u64::from_le_bytes);
+    }
+
+    /// Gets an unsigned 64 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    ///     false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x0102030405060708, buf.get_u64_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u64_ne(&mut self) -> u64 {
+        buf_get_impl!(self, u64::from_ne_bytes);
+    }
+
+    /// Gets a signed 64 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+    /// assert_eq!(0x0102030405060708, buf.get_i64());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i64(&mut self) -> i64 {
+        buf_get_impl!(self, i64::from_be_bytes);
+    }
+
+    /// Gets a signed 64 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x0102030405060708, buf.get_i64_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i64_le(&mut self) -> i64 {
+        buf_get_impl!(self, i64::from_le_bytes);
+    }
+
+    /// Gets a signed 64 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    ///     false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x0102030405060708, buf.get_i64_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i64_ne(&mut self) -> i64 {
+        buf_get_impl!(self, i64::from_ne_bytes);
+    }
+
+    /// Gets an unsigned 128 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u128(&mut self) -> u128 {
+        buf_get_impl!(self, u128::from_be_bytes);
+    }
+
+    /// Gets an unsigned 128 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u128_le(&mut self) -> u128 {
+        buf_get_impl!(self, u128::from_le_bytes);
+    }
+
+    /// Gets an unsigned 128 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    ///     false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_u128_ne(&mut self) -> u128 {
+        buf_get_impl!(self, u128::from_ne_bytes);
+    }
+
+    /// Gets a signed 128 bit integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i128(&mut self) -> i128 {
+        buf_get_impl!(self, i128::from_be_bytes);
+    }
+
+    /// Gets a signed 128 bit integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i128_le(&mut self) -> i128 {
+        buf_get_impl!(self, i128::from_le_bytes);
+    }
+
+    /// Gets a signed 128 bit integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    ///     false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_i128_ne(&mut self) -> i128 {
+        buf_get_impl!(self, i128::from_ne_bytes);
+    }
+
+    /// Gets an unsigned n-byte integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03 hello"[..];
+    /// assert_eq!(0x010203, buf.get_uint(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_uint(&mut self, nbytes: usize) -> u64 {
+        buf_get_impl!(be => self, u64, nbytes);
+    }
+
+    /// Gets an unsigned n-byte integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x010203, buf.get_uint_le(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_uint_le(&mut self, nbytes: usize) -> u64 {
+        buf_get_impl!(le => self, u64, nbytes);
+    }
+
+    /// Gets an unsigned n-byte integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03 hello",
+    ///     false => b"\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x010203, buf.get_uint_ne(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`, or
+    /// if `nbytes` is greater than 8.
+    fn get_uint_ne(&mut self, nbytes: usize) -> u64 {
+        if cfg!(target_endian = "big") {
+            self.get_uint(nbytes)
+        } else {
+            self.get_uint_le(nbytes)
+        }
+    }
+
+    /// Gets a signed n-byte integer from `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x01\x02\x03 hello"[..];
+    /// assert_eq!(0x010203, buf.get_int(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`, or
+    /// if `nbytes` is greater than 8.
+    fn get_int(&mut self, nbytes: usize) -> i64 {
+        buf_get_impl!(be => self, i64, nbytes);
+    }
+
+    /// Gets a signed n-byte integer from `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x03\x02\x01 hello"[..];
+    /// assert_eq!(0x010203, buf.get_int_le(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`, or
+    /// if `nbytes` is greater than 8.
+    fn get_int_le(&mut self, nbytes: usize) -> i64 {
+        buf_get_impl!(le => self, i64, nbytes);
+    }
+
+    /// Gets a signed n-byte integer from `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x01\x02\x03 hello",
+    ///     false => b"\x03\x02\x01 hello",
+    /// };
+    /// assert_eq!(0x010203, buf.get_int_ne(3));
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`, or
+    /// if `nbytes` is greater than 8.
+    fn get_int_ne(&mut self, nbytes: usize) -> i64 {
+        if cfg!(target_endian = "big") {
+            self.get_int(nbytes)
+        } else {
+            self.get_int_le(nbytes)
+        }
+    }
+
+    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
+    /// `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
+    /// assert_eq!(1.2f32, buf.get_f32());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f32(&mut self) -> f32 {
+        f32::from_bits(self.get_u32())
+    }
+
+    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
+    /// `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
+    /// assert_eq!(1.2f32, buf.get_f32_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f32_le(&mut self) -> f32 {
+        f32::from_bits(self.get_u32_le())
+    }
+
+    /// Gets an IEEE754 single-precision (4 bytes) floating point number from
+    /// `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x3F\x99\x99\x9A hello",
+    ///     false => b"\x9A\x99\x99\x3F hello",
+    /// };
+    /// assert_eq!(1.2f32, buf.get_f32_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f32_ne(&mut self) -> f32 {
+        f32::from_bits(self.get_u32_ne())
+    }
+
+    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
+    /// `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
+    /// assert_eq!(1.2f64, buf.get_f64());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f64(&mut self) -> f64 {
+        f64::from_bits(self.get_u64())
+    }
+
+    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
+    /// `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
+    /// assert_eq!(1.2f64, buf.get_f64_le());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f64_le(&mut self) -> f64 {
+        f64::from_bits(self.get_u64_le())
+    }
+
+    /// Gets an IEEE754 double-precision (8 bytes) floating point number from
+    /// `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    ///     true => b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello",
+    ///     false => b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello",
+    /// };
+    /// assert_eq!(1.2f64, buf.get_f64_ne());
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining data in `self`.
+    fn get_f64_ne(&mut self) -> f64 {
+        f64::from_bits(self.get_u64_ne())
+    }
+
+    /// Consumes `len` bytes inside self and returns new instance of `Bytes`
+    /// with this data.
+    ///
+    /// This function may be optimized by the underlying type to avoid actual
+    /// copies. For example, `Bytes` implementation will do a shallow copy
+    /// (ref-count increment).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// let bytes = (&b"hello world"[..]).copy_to_bytes(5);
+    /// assert_eq!(&bytes[..], &b"hello"[..]);
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `len > self.remaining()`.
+    fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
+        use super::BufMut;
+
+        if self.remaining() < len {
+            panic_advance(len, self.remaining());
+        }
+
+        let mut ret = crate::BytesMut::with_capacity(len);
+        ret.put(self.take(len));
+        ret.freeze()
+    }
+
+    /// 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};
+    ///
+    /// 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;
+    ///
+    /// let mut chain = b"hello "[..].chain(&b"world"[..]);
+    ///
+    /// let full = chain.copy_to_bytes(11);
+    /// assert_eq!(full.chunk(), 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::{Bytes, Buf};
+    /// 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")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    fn reader(self) -> Reader<Self>
+    where
+        Self: Sized,
+    {
+        reader::new(self)
+    }
+}
+
+macro_rules! deref_forward_buf {
+    () => {
+        #[inline]
+        fn remaining(&self) -> usize {
+            (**self).remaining()
+        }
+
+        #[inline]
+        fn chunk(&self) -> &[u8] {
+            (**self).chunk()
+        }
+
+        #[cfg(feature = "std")]
+        #[inline]
+        fn chunks_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize {
+            (**self).chunks_vectored(dst)
+        }
+
+        #[inline]
+        fn advance(&mut self, cnt: usize) {
+            (**self).advance(cnt)
+        }
+
+        #[inline]
+        fn has_remaining(&self) -> bool {
+            (**self).has_remaining()
+        }
+
+        #[inline]
+        fn copy_to_slice(&mut self, dst: &mut [u8]) {
+            (**self).copy_to_slice(dst)
+        }
+
+        #[inline]
+        fn get_u8(&mut self) -> u8 {
+            (**self).get_u8()
+        }
+
+        #[inline]
+        fn get_i8(&mut self) -> i8 {
+            (**self).get_i8()
+        }
+
+        #[inline]
+        fn get_u16(&mut self) -> u16 {
+            (**self).get_u16()
+        }
+
+        #[inline]
+        fn get_u16_le(&mut self) -> u16 {
+            (**self).get_u16_le()
+        }
+
+        #[inline]
+        fn get_u16_ne(&mut self) -> u16 {
+            (**self).get_u16_ne()
+        }
+
+        #[inline]
+        fn get_i16(&mut self) -> i16 {
+            (**self).get_i16()
+        }
+
+        #[inline]
+        fn get_i16_le(&mut self) -> i16 {
+            (**self).get_i16_le()
+        }
+
+        #[inline]
+        fn get_i16_ne(&mut self) -> i16 {
+            (**self).get_i16_ne()
+        }
+
+        #[inline]
+        fn get_u32(&mut self) -> u32 {
+            (**self).get_u32()
+        }
+
+        #[inline]
+        fn get_u32_le(&mut self) -> u32 {
+            (**self).get_u32_le()
+        }
+
+        #[inline]
+        fn get_u32_ne(&mut self) -> u32 {
+            (**self).get_u32_ne()
+        }
+
+        #[inline]
+        fn get_i32(&mut self) -> i32 {
+            (**self).get_i32()
+        }
+
+        #[inline]
+        fn get_i32_le(&mut self) -> i32 {
+            (**self).get_i32_le()
+        }
+
+        #[inline]
+        fn get_i32_ne(&mut self) -> i32 {
+            (**self).get_i32_ne()
+        }
+
+        #[inline]
+        fn get_u64(&mut self) -> u64 {
+            (**self).get_u64()
+        }
+
+        #[inline]
+        fn get_u64_le(&mut self) -> u64 {
+            (**self).get_u64_le()
+        }
+
+        #[inline]
+        fn get_u64_ne(&mut self) -> u64 {
+            (**self).get_u64_ne()
+        }
+
+        #[inline]
+        fn get_i64(&mut self) -> i64 {
+            (**self).get_i64()
+        }
+
+        #[inline]
+        fn get_i64_le(&mut self) -> i64 {
+            (**self).get_i64_le()
+        }
+
+        #[inline]
+        fn get_i64_ne(&mut self) -> i64 {
+            (**self).get_i64_ne()
+        }
+
+        #[inline]
+        fn get_uint(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint(nbytes)
+        }
+
+        #[inline]
+        fn get_uint_le(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint_le(nbytes)
+        }
+
+        #[inline]
+        fn get_uint_ne(&mut self, nbytes: usize) -> u64 {
+            (**self).get_uint_ne(nbytes)
+        }
+
+        #[inline]
+        fn get_int(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int(nbytes)
+        }
+
+        #[inline]
+        fn get_int_le(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int_le(nbytes)
+        }
+
+        #[inline]
+        fn get_int_ne(&mut self, nbytes: usize) -> i64 {
+            (**self).get_int_ne(nbytes)
+        }
+
+        #[inline]
+        fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
+            (**self).copy_to_bytes(len)
+        }
+    };
+}
+
+impl<T: Buf + ?Sized> Buf for &mut T {
+    deref_forward_buf!();
+}
+
+impl<T: Buf + ?Sized> Buf for Box<T> {
+    deref_forward_buf!();
+}
+
+impl Buf for &[u8] {
+    #[inline]
+    fn remaining(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk(&self) -> &[u8] {
+        self
+    }
+
+    #[inline]
+    fn advance(&mut self, cnt: usize) {
+        if self.len() < cnt {
+            panic_advance(cnt, self.len());
+        }
+
+        *self = &self[cnt..];
+    }
+
+    #[inline]
+    fn copy_to_slice(&mut self, dst: &mut [u8]) {
+        if self.len() < dst.len() {
+            panic_advance(dst.len(), self.len());
+        }
+
+        dst.copy_from_slice(&self[..dst.len()]);
+        self.advance(dst.len());
+    }
+}
+
+#[cfg(feature = "std")]
+impl<T: AsRef<[u8]>> Buf for std::io::Cursor<T> {
+    #[inline]
+    fn remaining(&self) -> usize {
+        saturating_sub_usize_u64(self.get_ref().as_ref().len(), self.position())
+    }
+
+    #[inline]
+    fn chunk(&self) -> &[u8] {
+        let slice = self.get_ref().as_ref();
+        let pos = min_u64_usize(self.position(), slice.len());
+        &slice[pos..]
+    }
+
+    #[inline]
+    fn advance(&mut self, cnt: usize) {
+        let len = self.get_ref().as_ref().len();
+        let pos = self.position();
+
+        // We intentionally allow `cnt == 0` here even if `pos > len`.
+        let max_cnt = saturating_sub_usize_u64(len, pos);
+        if cnt > max_cnt {
+            panic_advance(cnt, max_cnt);
+        }
+
+        // This will not overflow because either `cnt == 0` or the sum is not
+        // greater than `len`.
+        self.set_position(pos + cnt as u64);
+    }
+}
+
+// The existence of this function makes the compiler catch if the Buf
+// trait is "object-safe" or not.
+fn _assert_trait_object(_b: &dyn Buf) {}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/buf_mut.rs.html b/src/bytes/buf/buf_mut.rs.html new file mode 100644 index 000000000..d072b8db9 --- /dev/null +++ b/src/bytes/buf/buf_mut.rs.html @@ -0,0 +1,3284 @@ +buf_mut.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+
use crate::buf::{limit, Chain, Limit, UninitSlice};
+#[cfg(feature = "std")]
+use crate::buf::{writer, Writer};
+use crate::{panic_advance, panic_does_not_fit};
+
+use core::{mem, ptr, usize};
+
+use alloc::{boxed::Box, vec::Vec};
+
+/// A trait for values that provide sequential write access to bytes.
+///
+/// Write bytes to a buffer
+///
+/// A buffer stores bytes in memory such that write operations are infallible.
+/// The underlying storage may or may not be in contiguous memory. A `BufMut`
+/// value is a cursor into the buffer. Writing to `BufMut` advances the cursor
+/// position.
+///
+/// The simplest `BufMut` is a `Vec<u8>`.
+///
+/// ```
+/// use bytes::BufMut;
+///
+/// let mut buf = vec![];
+///
+/// buf.put(&b"hello world"[..]);
+///
+/// assert_eq!(buf, b"hello world");
+/// ```
+pub unsafe trait BufMut {
+    /// Returns the number of bytes that can be written from the current
+    /// position until the end of the buffer is reached.
+    ///
+    /// This value is greater than or equal to the length of the slice returned
+    /// by `chunk_mut()`.
+    ///
+    /// Writing to a `BufMut` may involve allocating more memory on the fly.
+    /// Implementations may fail before reaching the number of bytes indicated
+    /// by this method if they encounter an allocation failure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut dst = [0; 10];
+    /// let mut buf = &mut dst[..];
+    ///
+    /// let original_remaining = buf.remaining_mut();
+    /// buf.put(&b"hello"[..]);
+    ///
+    /// assert_eq!(original_remaining - 5, buf.remaining_mut());
+    /// ```
+    ///
+    /// # Implementer notes
+    ///
+    /// Implementations of `remaining_mut` should ensure that the return value
+    /// does not change unless a call is made to `advance_mut` or any other
+    /// function that is documented to change the `BufMut`'s current position.
+    ///
+    /// # Note
+    ///
+    /// `remaining_mut` may return value smaller than actual available space.
+    fn remaining_mut(&self) -> usize;
+
+    /// Advance the internal cursor of the BufMut
+    ///
+    /// The next call to `chunk_mut` will return a slice starting `cnt` bytes
+    /// further into the underlying buffer.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the next `cnt` bytes of `chunk` are
+    /// initialized.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = Vec::with_capacity(16);
+    ///
+    /// // Write some data
+    /// buf.chunk_mut()[0..2].copy_from_slice(b"he");
+    /// unsafe { buf.advance_mut(2) };
+    ///
+    /// // write more bytes
+    /// buf.chunk_mut()[0..3].copy_from_slice(b"llo");
+    ///
+    /// unsafe { buf.advance_mut(3); }
+    ///
+    /// assert_eq!(5, buf.len());
+    /// assert_eq!(buf, b"hello");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function **may** panic if `cnt > self.remaining_mut()`.
+    ///
+    /// # Implementer notes
+    ///
+    /// It is recommended for implementations of `advance_mut` to panic if
+    /// `cnt > self.remaining_mut()`. If the implementation does not panic,
+    /// the call must behave as if `cnt == self.remaining_mut()`.
+    ///
+    /// A call with `cnt == 0` should never panic and be a no-op.
+    unsafe fn advance_mut(&mut self, cnt: usize);
+
+    /// Returns true if there is space in `self` for more bytes.
+    ///
+    /// This is equivalent to `self.remaining_mut() != 0`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut dst = [0; 5];
+    /// let mut buf = &mut dst[..];
+    ///
+    /// assert!(buf.has_remaining_mut());
+    ///
+    /// buf.put(&b"hello"[..]);
+    ///
+    /// assert!(!buf.has_remaining_mut());
+    /// ```
+    #[inline]
+    fn has_remaining_mut(&self) -> bool {
+        self.remaining_mut() > 0
+    }
+
+    /// Returns a mutable slice starting at the current BufMut position and of
+    /// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the
+    /// whole remainder of the buffer (this allows non-continuous implementation).
+    ///
+    /// This is a lower level function. Most operations are done with other
+    /// functions.
+    ///
+    /// The returned byte slice may represent uninitialized memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = Vec::with_capacity(16);
+    ///
+    /// unsafe {
+    ///     // MaybeUninit::as_mut_ptr
+    ///     buf.chunk_mut()[0..].as_mut_ptr().write(b'h');
+    ///     buf.chunk_mut()[1..].as_mut_ptr().write(b'e');
+    ///
+    ///     buf.advance_mut(2);
+    ///
+    ///     buf.chunk_mut()[0..].as_mut_ptr().write(b'l');
+    ///     buf.chunk_mut()[1..].as_mut_ptr().write(b'l');
+    ///     buf.chunk_mut()[2..].as_mut_ptr().write(b'o');
+    ///
+    ///     buf.advance_mut(3);
+    /// }
+    ///
+    /// assert_eq!(5, buf.len());
+    /// assert_eq!(buf, b"hello");
+    /// ```
+    ///
+    /// # Implementer notes
+    ///
+    /// This function should never panic. `chunk_mut` should return an empty
+    /// slice **if and only if** `remaining_mut()` returns 0. In other words,
+    /// `chunk_mut()` returning an empty slice implies that `remaining_mut()` will
+    /// return 0 and `remaining_mut()` returning 0 implies that `chunk_mut()` will
+    /// return an empty slice.
+    ///
+    /// This function may trigger an out-of-memory abort if it tries to allocate
+    /// memory and fails to do so.
+    // The `chunk_mut` method was previously called `bytes_mut`. This alias makes the
+    // rename more easily discoverable.
+    #[cfg_attr(docsrs, doc(alias = "bytes_mut"))]
+    fn chunk_mut(&mut self) -> &mut UninitSlice;
+
+    /// Transfer bytes into `self` from `src` and advance the cursor by the
+    /// number of bytes written.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    ///
+    /// buf.put_u8(b'h');
+    /// buf.put(&b"ello"[..]);
+    /// buf.put(&b" world"[..]);
+    ///
+    /// assert_eq!(buf, b"hello world");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if `self` does not have enough capacity to contain `src`.
+    #[inline]
+    fn put<T: super::Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
+        if self.remaining_mut() < src.remaining() {
+            panic_advance(src.remaining(), self.remaining_mut());
+        }
+
+        while src.has_remaining() {
+            let s = src.chunk();
+            let d = self.chunk_mut();
+            let cnt = usize::min(s.len(), d.len());
+
+            d[..cnt].copy_from_slice(&s[..cnt]);
+
+            // SAFETY: We just initialized `cnt` bytes in `self`.
+            unsafe { self.advance_mut(cnt) };
+            src.advance(cnt);
+        }
+    }
+
+    /// Transfer bytes into `self` from `src` and advance the cursor by the
+    /// number of bytes written.
+    ///
+    /// `self` must have enough remaining capacity to contain all of `src`.
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut dst = [0; 6];
+    ///
+    /// {
+    ///     let mut buf = &mut dst[..];
+    ///     buf.put_slice(b"hello");
+    ///
+    ///     assert_eq!(1, buf.remaining_mut());
+    /// }
+    ///
+    /// assert_eq!(b"hello\0", &dst);
+    /// ```
+    #[inline]
+    fn put_slice(&mut self, mut src: &[u8]) {
+        if self.remaining_mut() < src.len() {
+            panic_advance(src.len(), self.remaining_mut());
+        }
+
+        while !src.is_empty() {
+            let dst = self.chunk_mut();
+            let cnt = usize::min(src.len(), dst.len());
+
+            dst[..cnt].copy_from_slice(&src[..cnt]);
+            src = &src[cnt..];
+
+            // SAFETY: We just initialized `cnt` bytes in `self`.
+            unsafe { self.advance_mut(cnt) };
+        }
+    }
+
+    /// Put `cnt` bytes `val` into `self`.
+    ///
+    /// Logically equivalent to calling `self.put_u8(val)` `cnt` times, but may work faster.
+    ///
+    /// `self` must have at least `cnt` remaining capacity.
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut dst = [0; 6];
+    ///
+    /// {
+    ///     let mut buf = &mut dst[..];
+    ///     buf.put_bytes(b'a', 4);
+    ///
+    ///     assert_eq!(2, buf.remaining_mut());
+    /// }
+    ///
+    /// assert_eq!(b"aaaa\0\0", &dst);
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_bytes(&mut self, val: u8, mut cnt: usize) {
+        if self.remaining_mut() < cnt {
+            panic_advance(cnt, self.remaining_mut());
+        }
+
+        while cnt > 0 {
+            let dst = self.chunk_mut();
+            let dst_len = usize::min(dst.len(), cnt);
+            // SAFETY: The pointer is valid for `dst_len <= dst.len()` bytes.
+            unsafe { core::ptr::write_bytes(dst.as_mut_ptr(), val, dst_len) };
+            // SAFETY: We just initialized `dst_len` bytes in `self`.
+            unsafe { self.advance_mut(dst_len) };
+            cnt -= dst_len;
+        }
+    }
+
+    /// Writes an unsigned 8 bit integer to `self`.
+    ///
+    /// The current position is advanced by 1.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u8(0x01);
+    /// assert_eq!(buf, b"\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u8(&mut self, n: u8) {
+        let src = [n];
+        self.put_slice(&src);
+    }
+
+    /// Writes a signed 8 bit integer to `self`.
+    ///
+    /// The current position is advanced by 1.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i8(0x01);
+    /// assert_eq!(buf, b"\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i8(&mut self, n: i8) {
+        let src = [n as u8];
+        self.put_slice(&src)
+    }
+
+    /// Writes an unsigned 16 bit integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u16(0x0809);
+    /// assert_eq!(buf, b"\x08\x09");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u16(&mut self, n: u16) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes an unsigned 16 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u16_le(0x0809);
+    /// assert_eq!(buf, b"\x09\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u16_le(&mut self, n: u16) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes an unsigned 16 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u16_ne(0x0809);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x08\x09");
+    /// } else {
+    ///     assert_eq!(buf, b"\x09\x08");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u16_ne(&mut self, n: u16) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes a signed 16 bit integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i16(0x0809);
+    /// assert_eq!(buf, b"\x08\x09");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i16(&mut self, n: i16) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes a signed 16 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i16_le(0x0809);
+    /// assert_eq!(buf, b"\x09\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i16_le(&mut self, n: i16) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes a signed 16 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 2.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i16_ne(0x0809);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x08\x09");
+    /// } else {
+    ///     assert_eq!(buf, b"\x09\x08");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i16_ne(&mut self, n: i16) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes an unsigned 32 bit integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u32(0x0809A0A1);
+    /// assert_eq!(buf, b"\x08\x09\xA0\xA1");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u32(&mut self, n: u32) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes an unsigned 32 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u32_le(0x0809A0A1);
+    /// assert_eq!(buf, b"\xA1\xA0\x09\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u32_le(&mut self, n: u32) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes an unsigned 32 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u32_ne(0x0809A0A1);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x08\x09\xA0\xA1");
+    /// } else {
+    ///     assert_eq!(buf, b"\xA1\xA0\x09\x08");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u32_ne(&mut self, n: u32) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes a signed 32 bit integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i32(0x0809A0A1);
+    /// assert_eq!(buf, b"\x08\x09\xA0\xA1");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i32(&mut self, n: i32) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes a signed 32 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i32_le(0x0809A0A1);
+    /// assert_eq!(buf, b"\xA1\xA0\x09\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i32_le(&mut self, n: i32) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes a signed 32 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i32_ne(0x0809A0A1);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x08\x09\xA0\xA1");
+    /// } else {
+    ///     assert_eq!(buf, b"\xA1\xA0\x09\x08");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i32_ne(&mut self, n: i32) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes an unsigned 64 bit integer to `self` in the big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u64(0x0102030405060708);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u64(&mut self, n: u64) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes an unsigned 64 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u64_le(0x0102030405060708);
+    /// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u64_le(&mut self, n: u64) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes an unsigned 64 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u64_ne(0x0102030405060708);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+    /// } else {
+    ///     assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u64_ne(&mut self, n: u64) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes a signed 64 bit integer to `self` in the big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i64(0x0102030405060708);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i64(&mut self, n: i64) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes a signed 64 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i64_le(0x0102030405060708);
+    /// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i64_le(&mut self, n: i64) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes a signed 64 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i64_ne(0x0102030405060708);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+    /// } else {
+    ///     assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i64_ne(&mut self, n: i64) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes an unsigned 128 bit integer to `self` in the big-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u128(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u128(&mut self, n: u128) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes an unsigned 128 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u128_le(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u128_le(&mut self, n: u128) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes an unsigned 128 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_u128_ne(0x01020304050607080910111213141516);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// } else {
+    ///     assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_u128_ne(&mut self, n: u128) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes a signed 128 bit integer to `self` in the big-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i128(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i128(&mut self, n: i128) {
+        self.put_slice(&n.to_be_bytes())
+    }
+
+    /// Writes a signed 128 bit integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i128_le(0x01020304050607080910111213141516);
+    /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i128_le(&mut self, n: i128) {
+        self.put_slice(&n.to_le_bytes())
+    }
+
+    /// Writes a signed 128 bit integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_i128_ne(0x01020304050607080910111213141516);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+    /// } else {
+    ///     assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_i128_ne(&mut self, n: i128) {
+        self.put_slice(&n.to_ne_bytes())
+    }
+
+    /// Writes an unsigned n-byte integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_uint(0x010203, 3);
+    /// assert_eq!(buf, b"\x01\x02\x03");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_uint(&mut self, n: u64, nbytes: usize) {
+        let start = match mem::size_of_val(&n).checked_sub(nbytes) {
+            Some(start) => start,
+            None => panic_does_not_fit(nbytes, mem::size_of_val(&n)),
+        };
+
+        self.put_slice(&n.to_be_bytes()[start..]);
+    }
+
+    /// Writes an unsigned n-byte integer to `self` in the little-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_uint_le(0x010203, 3);
+    /// assert_eq!(buf, b"\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_uint_le(&mut self, n: u64, nbytes: usize) {
+        let slice = n.to_le_bytes();
+        let slice = match slice.get(..nbytes) {
+            Some(slice) => slice,
+            None => panic_does_not_fit(nbytes, slice.len()),
+        };
+
+        self.put_slice(slice);
+    }
+
+    /// Writes an unsigned n-byte integer to `self` in the native-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_uint_ne(0x010203, 3);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03");
+    /// } else {
+    ///     assert_eq!(buf, b"\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_uint_ne(&mut self, n: u64, nbytes: usize) {
+        if cfg!(target_endian = "big") {
+            self.put_uint(n, nbytes)
+        } else {
+            self.put_uint_le(n, nbytes)
+        }
+    }
+
+    /// Writes low `nbytes` of a signed integer to `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_int(0x0504010203, 3);
+    /// assert_eq!(buf, b"\x01\x02\x03");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_int(&mut self, n: i64, nbytes: usize) {
+        let start = match mem::size_of_val(&n).checked_sub(nbytes) {
+            Some(start) => start,
+            None => panic_does_not_fit(nbytes, mem::size_of_val(&n)),
+        };
+
+        self.put_slice(&n.to_be_bytes()[start..]);
+    }
+
+    /// Writes low `nbytes` of a signed integer to `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_int_le(0x0504010203, 3);
+    /// assert_eq!(buf, b"\x03\x02\x01");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_int_le(&mut self, n: i64, nbytes: usize) {
+        let slice = n.to_le_bytes();
+        let slice = match slice.get(..nbytes) {
+            Some(slice) => slice,
+            None => panic_does_not_fit(nbytes, slice.len()),
+        };
+
+        self.put_slice(slice);
+    }
+
+    /// Writes low `nbytes` of a signed integer to `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by `nbytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_int_ne(0x010203, 3);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x01\x02\x03");
+    /// } else {
+    ///     assert_eq!(buf, b"\x03\x02\x01");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self` or if `nbytes` is greater than 8.
+    #[inline]
+    fn put_int_ne(&mut self, n: i64, nbytes: usize) {
+        if cfg!(target_endian = "big") {
+            self.put_int(n, nbytes)
+        } else {
+            self.put_int_le(n, nbytes)
+        }
+    }
+
+    /// Writes  an IEEE754 single-precision (4 bytes) floating point number to
+    /// `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f32(1.2f32);
+    /// assert_eq!(buf, b"\x3F\x99\x99\x9A");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f32(&mut self, n: f32) {
+        self.put_u32(n.to_bits());
+    }
+
+    /// Writes  an IEEE754 single-precision (4 bytes) floating point number to
+    /// `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f32_le(1.2f32);
+    /// assert_eq!(buf, b"\x9A\x99\x99\x3F");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f32_le(&mut self, n: f32) {
+        self.put_u32_le(n.to_bits());
+    }
+
+    /// Writes an IEEE754 single-precision (4 bytes) floating point number to
+    /// `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 4.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f32_ne(1.2f32);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x3F\x99\x99\x9A");
+    /// } else {
+    ///     assert_eq!(buf, b"\x9A\x99\x99\x3F");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f32_ne(&mut self, n: f32) {
+        self.put_u32_ne(n.to_bits());
+    }
+
+    /// Writes  an IEEE754 double-precision (8 bytes) floating point number to
+    /// `self` in big-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f64(1.2f64);
+    /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f64(&mut self, n: f64) {
+        self.put_u64(n.to_bits());
+    }
+
+    /// Writes  an IEEE754 double-precision (8 bytes) floating point number to
+    /// `self` in little-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f64_le(1.2f64);
+    /// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f64_le(&mut self, n: f64) {
+        self.put_u64_le(n.to_bits());
+    }
+
+    /// Writes  an IEEE754 double-precision (8 bytes) floating point number to
+    /// `self` in native-endian byte order.
+    ///
+    /// The current position is advanced by 8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut buf = vec![];
+    /// buf.put_f64_ne(1.2f64);
+    /// if cfg!(target_endian = "big") {
+    ///     assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+    /// } else {
+    ///     assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+    /// }
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// This function panics if there is not enough remaining capacity in
+    /// `self`.
+    #[inline]
+    fn put_f64_ne(&mut self, n: f64) {
+        self.put_u64_ne(n.to_bits());
+    }
+
+    /// Creates an adaptor which can write at most `limit` bytes to `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let arr = &mut [0u8; 128][..];
+    /// assert_eq!(arr.remaining_mut(), 128);
+    ///
+    /// let dst = arr.limit(10);
+    /// assert_eq!(dst.remaining_mut(), 10);
+    /// ```
+    #[inline]
+    fn limit(self, limit: usize) -> Limit<Self>
+    where
+        Self: Sized,
+    {
+        limit::new(self, limit)
+    }
+
+    /// 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;
+    /// 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")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    #[inline]
+    fn writer(self) -> Writer<Self>
+    where
+        Self: Sized,
+    {
+        writer::new(self)
+    }
+
+    /// Creates an adapter which will chain this buffer with another.
+    ///
+    /// The returned `BufMut` instance will first write to all bytes from
+    /// `self`. Afterwards, it will write to `next`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut a = [0u8; 5];
+    /// let mut b = [0u8; 6];
+    ///
+    /// let mut chain = (&mut a[..]).chain_mut(&mut b[..]);
+    ///
+    /// chain.put_slice(b"hello world");
+    ///
+    /// assert_eq!(&a[..], b"hello");
+    /// assert_eq!(&b[..], b" world");
+    /// ```
+    #[inline]
+    fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
+    where
+        Self: Sized,
+    {
+        Chain::new(self, next)
+    }
+}
+
+macro_rules! deref_forward_bufmut {
+    () => {
+        #[inline]
+        fn remaining_mut(&self) -> usize {
+            (**self).remaining_mut()
+        }
+
+        #[inline]
+        fn chunk_mut(&mut self) -> &mut UninitSlice {
+            (**self).chunk_mut()
+        }
+
+        #[inline]
+        unsafe fn advance_mut(&mut self, cnt: usize) {
+            (**self).advance_mut(cnt)
+        }
+
+        #[inline]
+        fn put_slice(&mut self, src: &[u8]) {
+            (**self).put_slice(src)
+        }
+
+        #[inline]
+        fn put_u8(&mut self, n: u8) {
+            (**self).put_u8(n)
+        }
+
+        #[inline]
+        fn put_i8(&mut self, n: i8) {
+            (**self).put_i8(n)
+        }
+
+        #[inline]
+        fn put_u16(&mut self, n: u16) {
+            (**self).put_u16(n)
+        }
+
+        #[inline]
+        fn put_u16_le(&mut self, n: u16) {
+            (**self).put_u16_le(n)
+        }
+
+        #[inline]
+        fn put_u16_ne(&mut self, n: u16) {
+            (**self).put_u16_ne(n)
+        }
+
+        #[inline]
+        fn put_i16(&mut self, n: i16) {
+            (**self).put_i16(n)
+        }
+
+        #[inline]
+        fn put_i16_le(&mut self, n: i16) {
+            (**self).put_i16_le(n)
+        }
+
+        #[inline]
+        fn put_i16_ne(&mut self, n: i16) {
+            (**self).put_i16_ne(n)
+        }
+
+        #[inline]
+        fn put_u32(&mut self, n: u32) {
+            (**self).put_u32(n)
+        }
+
+        #[inline]
+        fn put_u32_le(&mut self, n: u32) {
+            (**self).put_u32_le(n)
+        }
+
+        #[inline]
+        fn put_u32_ne(&mut self, n: u32) {
+            (**self).put_u32_ne(n)
+        }
+
+        #[inline]
+        fn put_i32(&mut self, n: i32) {
+            (**self).put_i32(n)
+        }
+
+        #[inline]
+        fn put_i32_le(&mut self, n: i32) {
+            (**self).put_i32_le(n)
+        }
+
+        #[inline]
+        fn put_i32_ne(&mut self, n: i32) {
+            (**self).put_i32_ne(n)
+        }
+
+        #[inline]
+        fn put_u64(&mut self, n: u64) {
+            (**self).put_u64(n)
+        }
+
+        #[inline]
+        fn put_u64_le(&mut self, n: u64) {
+            (**self).put_u64_le(n)
+        }
+
+        #[inline]
+        fn put_u64_ne(&mut self, n: u64) {
+            (**self).put_u64_ne(n)
+        }
+
+        #[inline]
+        fn put_i64(&mut self, n: i64) {
+            (**self).put_i64(n)
+        }
+
+        #[inline]
+        fn put_i64_le(&mut self, n: i64) {
+            (**self).put_i64_le(n)
+        }
+
+        #[inline]
+        fn put_i64_ne(&mut self, n: i64) {
+            (**self).put_i64_ne(n)
+        }
+    };
+}
+
+unsafe impl<T: BufMut + ?Sized> BufMut for &mut T {
+    deref_forward_bufmut!();
+}
+
+unsafe impl<T: BufMut + ?Sized> BufMut for Box<T> {
+    deref_forward_bufmut!();
+}
+
+unsafe impl BufMut for &mut [u8] {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        UninitSlice::new(self)
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        if self.len() < cnt {
+            panic_advance(cnt, self.len());
+        }
+
+        // Lifetime dance taken from `impl Write for &mut [u8]`.
+        let (_, b) = core::mem::replace(self, &mut []).split_at_mut(cnt);
+        *self = b;
+    }
+
+    #[inline]
+    fn put_slice(&mut self, src: &[u8]) {
+        if self.len() < src.len() {
+            panic_advance(src.len(), self.len());
+        }
+
+        self[..src.len()].copy_from_slice(src);
+        // SAFETY: We just initialized `src.len()` bytes.
+        unsafe { self.advance_mut(src.len()) };
+    }
+
+    #[inline]
+    fn put_bytes(&mut self, val: u8, cnt: usize) {
+        if self.len() < cnt {
+            panic_advance(cnt, self.len());
+        }
+
+        // SAFETY: We just checked that the pointer is valid for `cnt` bytes.
+        unsafe {
+            ptr::write_bytes(self.as_mut_ptr(), val, cnt);
+            self.advance_mut(cnt);
+        }
+    }
+}
+
+unsafe impl BufMut for &mut [core::mem::MaybeUninit<u8>] {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        UninitSlice::uninit(self)
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        if self.len() < cnt {
+            panic_advance(cnt, self.len());
+        }
+
+        // Lifetime dance taken from `impl Write for &mut [u8]`.
+        let (_, b) = core::mem::replace(self, &mut []).split_at_mut(cnt);
+        *self = b;
+    }
+
+    #[inline]
+    fn put_slice(&mut self, src: &[u8]) {
+        if self.len() < src.len() {
+            panic_advance(src.len(), self.len());
+        }
+
+        // SAFETY: We just checked that the pointer is valid for `src.len()` bytes.
+        unsafe {
+            ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr().cast(), src.len());
+            self.advance_mut(src.len());
+        }
+    }
+
+    #[inline]
+    fn put_bytes(&mut self, val: u8, cnt: usize) {
+        if self.len() < cnt {
+            panic_advance(cnt, self.len());
+        }
+
+        // SAFETY: We just checked that the pointer is valid for `cnt` bytes.
+        unsafe {
+            ptr::write_bytes(self.as_mut_ptr() as *mut u8, val, cnt);
+            self.advance_mut(cnt);
+        }
+    }
+}
+
+unsafe impl BufMut for Vec<u8> {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        // A vector can never have more than isize::MAX bytes
+        core::isize::MAX as usize - self.len()
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        let len = self.len();
+        let remaining = self.capacity() - len;
+
+        if remaining < cnt {
+            panic_advance(cnt, remaining);
+        }
+
+        // Addition will not overflow since the sum is at most the capacity.
+        self.set_len(len + cnt);
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        if self.capacity() == self.len() {
+            self.reserve(64); // Grow the vec
+        }
+
+        let cap = self.capacity();
+        let len = self.len();
+
+        let ptr = self.as_mut_ptr();
+        // SAFETY: Since `ptr` is valid for `cap` bytes, `ptr.add(len)` must be
+        // valid for `cap - len` bytes. The subtraction will not underflow since
+        // `len <= cap`.
+        unsafe { UninitSlice::from_raw_parts_mut(ptr.add(len), cap - len) }
+    }
+
+    // Specialize these methods so they can skip checking `remaining_mut`
+    // and `advance_mut`.
+    #[inline]
+    fn put<T: super::Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
+        // In case the src isn't contiguous, reserve upfront.
+        self.reserve(src.remaining());
+
+        while src.has_remaining() {
+            let s = src.chunk();
+            let l = s.len();
+            self.extend_from_slice(s);
+            src.advance(l);
+        }
+    }
+
+    #[inline]
+    fn put_slice(&mut self, src: &[u8]) {
+        self.extend_from_slice(src);
+    }
+
+    #[inline]
+    fn put_bytes(&mut self, val: u8, cnt: usize) {
+        // If the addition overflows, then the `resize` will fail.
+        let new_len = self.len().saturating_add(cnt);
+        self.resize(new_len, val);
+    }
+}
+
+// The existence of this function makes the compiler catch if the BufMut
+// trait is "object-safe" or not.
+fn _assert_trait_object(_b: &dyn BufMut) {}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/chain.rs.html b/src/bytes/buf/chain.rs.html new file mode 100644 index 000000000..addd8564c --- /dev/null +++ b/src/bytes/buf/chain.rs.html @@ -0,0 +1,482 @@ +chain.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+
use crate::buf::{IntoIter, UninitSlice};
+use crate::{Buf, BufMut, Bytes};
+
+#[cfg(feature = "std")]
+use std::io::IoSlice;
+
+/// 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};
+///
+/// let mut buf = (&b"hello "[..])
+///     .chain(&b"world"[..]);
+///
+/// let full: Bytes = buf.copy_to_bytes(11);
+/// assert_eq!(full[..], b"hello world"[..]);
+/// ```
+///
+/// [`Buf::chain`]: Buf::chain
+#[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(crate) fn new(a: T, b: U) -> Chain<T, U> {
+        Chain { a, b }
+    }
+
+    /// Gets a reference to the first underlying `Buf`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Buf;
+    ///
+    /// 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;
+    ///
+    /// let mut buf = (&b"hello"[..])
+    ///     .chain(&b"world"[..]);
+    ///
+    /// buf.first_mut().advance(1);
+    ///
+    /// let full = buf.copy_to_bytes(9);
+    /// 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;
+    ///
+    /// 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;
+    ///
+    /// let mut buf = (&b"hello "[..])
+    ///     .chain(&b"world"[..]);
+    ///
+    /// buf.last_mut().advance(1);
+    ///
+    /// let full = buf.copy_to_bytes(10);
+    /// 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;
+    ///
+    /// 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().saturating_add(self.b.remaining())
+    }
+
+    fn chunk(&self) -> &[u8] {
+        if self.a.has_remaining() {
+            self.a.chunk()
+        } else {
+            self.b.chunk()
+        }
+    }
+
+    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 chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
+        let mut n = self.a.chunks_vectored(dst);
+        n += self.b.chunks_vectored(&mut dst[n..]);
+        n
+    }
+
+    fn copy_to_bytes(&mut self, len: usize) -> Bytes {
+        let a_rem = self.a.remaining();
+        if a_rem >= len {
+            self.a.copy_to_bytes(len)
+        } else if a_rem == 0 {
+            self.b.copy_to_bytes(len)
+        } else {
+            assert!(
+                len - a_rem <= self.b.remaining(),
+                "`len` greater than remaining"
+            );
+            let mut ret = crate::BytesMut::with_capacity(len);
+            ret.put(&mut self.a);
+            ret.put((&mut self.b).take(len - a_rem));
+            ret.freeze()
+        }
+    }
+}
+
+unsafe impl<T, U> BufMut for Chain<T, U>
+where
+    T: BufMut,
+    U: BufMut,
+{
+    fn remaining_mut(&self) -> usize {
+        self.a
+            .remaining_mut()
+            .saturating_add(self.b.remaining_mut())
+    }
+
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        if self.a.has_remaining_mut() {
+            self.a.chunk_mut()
+        } else {
+            self.b.chunk_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);
+    }
+}
+
+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)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/iter.rs.html b/src/bytes/buf/iter.rs.html new file mode 100644 index 000000000..766cf213a --- /dev/null +++ b/src/bytes/buf/iter.rs.html @@ -0,0 +1,256 @@ +iter.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+
use crate::Buf;
+
+/// Iterator over the bytes contained by the buffer.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use bytes::Bytes;
+///
+/// let buf = Bytes::from(&b"abc"[..]);
+/// let mut iter = buf.into_iter();
+///
+/// assert_eq!(iter.next(), Some(b'a'));
+/// assert_eq!(iter.next(), Some(b'b'));
+/// assert_eq!(iter.next(), Some(b'c'));
+/// assert_eq!(iter.next(), None);
+/// ```
+#[derive(Debug)]
+pub struct IntoIter<T> {
+    inner: T,
+}
+
+impl<T> IntoIter<T> {
+    /// Creates an iterator over the bytes contained by the buffer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let buf = Bytes::from_static(b"abc");
+    /// let mut iter = buf.into_iter();
+    ///
+    /// assert_eq!(iter.next(), Some(b'a'));
+    /// assert_eq!(iter.next(), Some(b'b'));
+    /// assert_eq!(iter.next(), Some(b'c'));
+    /// assert_eq!(iter.next(), None);
+    /// ```
+    pub fn new(inner: T) -> IntoIter<T> {
+        IntoIter { inner }
+    }
+
+    /// Consumes this `IntoIter`, returning the underlying value.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use bytes::{Buf, Bytes};
+    ///
+    /// let buf = Bytes::from(&b"abc"[..]);
+    /// let mut iter = buf.into_iter();
+    ///
+    /// assert_eq!(iter.next(), Some(b'a'));
+    ///
+    /// let buf = iter.into_inner();
+    /// assert_eq!(2, buf.remaining());
+    /// ```
+    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, Bytes};
+    ///
+    /// let buf = Bytes::from(&b"abc"[..]);
+    /// let mut iter = buf.into_iter();
+    ///
+    /// assert_eq!(iter.next(), Some(b'a'));
+    ///
+    /// assert_eq!(2, iter.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, BytesMut};
+    ///
+    /// let buf = BytesMut::from(&b"abc"[..]);
+    /// let mut iter = buf.into_iter();
+    ///
+    /// assert_eq!(iter.next(), Some(b'a'));
+    ///
+    /// iter.get_mut().advance(1);
+    ///
+    /// assert_eq!(iter.next(), Some(b'c'));
+    /// ```
+    pub fn get_mut(&mut self) -> &mut T {
+        &mut self.inner
+    }
+}
+
+impl<T: Buf> Iterator for IntoIter<T> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<u8> {
+        if !self.inner.has_remaining() {
+            return None;
+        }
+
+        let b = self.inner.chunk()[0];
+        self.inner.advance(1);
+
+        Some(b)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let rem = self.inner.remaining();
+        (rem, Some(rem))
+    }
+}
+
+impl<T: Buf> ExactSizeIterator for IntoIter<T> {}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/limit.rs.html b/src/bytes/buf/limit.rs.html new file mode 100644 index 000000000..c4ed6d617 --- /dev/null +++ b/src/bytes/buf/limit.rs.html @@ -0,0 +1,152 @@ +limit.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+
use crate::buf::UninitSlice;
+use crate::BufMut;
+
+use core::cmp;
+
+/// A `BufMut` adapter which limits the amount of bytes that can be written
+/// to an underlying buffer.
+#[derive(Debug)]
+pub struct Limit<T> {
+    inner: T,
+    limit: usize,
+}
+
+pub(super) fn new<T>(inner: T, limit: usize) -> Limit<T> {
+    Limit { inner, limit }
+}
+
+impl<T> Limit<T> {
+    /// Consumes this `Limit`, returning the underlying value.
+    pub fn into_inner(self) -> T {
+        self.inner
+    }
+
+    /// Gets a reference to the underlying `BufMut`.
+    ///
+    /// It is inadvisable to directly write to the underlying `BufMut`.
+    pub fn get_ref(&self) -> &T {
+        &self.inner
+    }
+
+    /// Gets a mutable reference to the underlying `BufMut`.
+    ///
+    /// It is inadvisable to directly write to the underlying `BufMut`.
+    pub fn get_mut(&mut self) -> &mut T {
+        &mut self.inner
+    }
+
+    /// Returns the maximum number of bytes that can be written
+    ///
+    /// # Note
+    ///
+    /// If the inner `BufMut` has fewer bytes than indicated by this method then
+    /// that is the actual number of available bytes.
+    pub fn limit(&self) -> usize {
+        self.limit
+    }
+
+    /// Sets the maximum number of bytes that can be written.
+    ///
+    /// # Note
+    ///
+    /// If the inner `BufMut` has fewer bytes than `lim` then that is the actual
+    /// number of available bytes.
+    pub fn set_limit(&mut self, lim: usize) {
+        self.limit = lim
+    }
+}
+
+unsafe impl<T: BufMut> BufMut for Limit<T> {
+    fn remaining_mut(&self) -> usize {
+        cmp::min(self.inner.remaining_mut(), self.limit)
+    }
+
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        let bytes = self.inner.chunk_mut();
+        let end = cmp::min(bytes.len(), self.limit);
+        &mut bytes[..end]
+    }
+
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        assert!(cnt <= self.limit);
+        self.inner.advance_mut(cnt);
+        self.limit -= cnt;
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/mod.rs.html b/src/bytes/buf/mod.rs.html new file mode 100644 index 000000000..fbd7ae7ce --- /dev/null +++ b/src/bytes/buf/mod.rs.html @@ -0,0 +1,80 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+
//! Utilities for working with buffers.
+//!
+//! A buffer is any structure that contains a sequence of bytes. The bytes may
+//! or may not be stored in contiguous memory. This module contains traits used
+//! to abstract over buffers as well as utilities for working with buffer types.
+//!
+//! # `Buf`, `BufMut`
+//!
+//! These are the two foundational traits for abstractly working with buffers.
+//! They can be thought as iterators for byte structures. They offer additional
+//! performance over `Iterator` by providing an API optimized for byte slices.
+//!
+//! See [`Buf`] and [`BufMut`] for more details.
+//!
+//! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure)
+
+mod buf_impl;
+mod buf_mut;
+mod chain;
+mod iter;
+mod limit;
+#[cfg(feature = "std")]
+mod reader;
+mod take;
+mod uninit_slice;
+mod vec_deque;
+#[cfg(feature = "std")]
+mod writer;
+
+pub use self::buf_impl::Buf;
+pub use self::buf_mut::BufMut;
+pub use self::chain::Chain;
+pub use self::iter::IntoIter;
+pub use self::limit::Limit;
+pub use self::take::Take;
+pub use self::uninit_slice::UninitSlice;
+
+#[cfg(feature = "std")]
+pub use self::{reader::Reader, writer::Writer};
+
+
\ No newline at end of file diff --git a/src/bytes/buf/reader.rs.html b/src/bytes/buf/reader.rs.html new file mode 100644 index 000000000..a32bc56c4 --- /dev/null +++ b/src/bytes/buf/reader.rs.html @@ -0,0 +1,164 @@ +reader.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+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()`](Buf::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;
+    ///
+    /// let 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;
+    /// 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.chunk())
+    }
+    fn consume(&mut self, amt: usize) {
+        self.buf.advance(amt)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/take.rs.html b/src/bytes/buf/take.rs.html new file mode 100644 index 000000000..e1c5f52c7 --- /dev/null +++ b/src/bytes/buf/take.rs.html @@ -0,0 +1,312 @@ +take.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+
use crate::{Buf, Bytes};
+
+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()`](Buf::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, BufMut};
+    ///
+    /// 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;
+    ///
+    /// let 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};
+    ///
+    /// 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;
+    ///
+    /// 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};
+    ///
+    /// 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 chunk(&self) -> &[u8] {
+        let bytes = self.inner.chunk();
+        &bytes[..cmp::min(bytes.len(), self.limit)]
+    }
+
+    fn advance(&mut self, cnt: usize) {
+        assert!(cnt <= self.limit);
+        self.inner.advance(cnt);
+        self.limit -= cnt;
+    }
+
+    fn copy_to_bytes(&mut self, len: usize) -> Bytes {
+        assert!(len <= self.remaining(), "`len` greater than remaining");
+
+        let r = self.inner.copy_to_bytes(len);
+        self.limit -= len;
+        r
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/uninit_slice.rs.html b/src/bytes/buf/uninit_slice.rs.html new file mode 100644 index 000000000..d474bbe44 --- /dev/null +++ b/src/bytes/buf/uninit_slice.rs.html @@ -0,0 +1,516 @@ +uninit_slice.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+
use core::fmt;
+use core::mem::MaybeUninit;
+use core::ops::{
+    Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
+};
+
+/// Uninitialized byte slice.
+///
+/// Returned by `BufMut::chunk_mut()`, the referenced byte slice may be
+/// uninitialized. The wrapper provides safe access without introducing
+/// undefined behavior.
+///
+/// The safety invariants of this wrapper are:
+///
+///  1. Reading from an `UninitSlice` is undefined behavior.
+///  2. Writing uninitialized bytes to an `UninitSlice` is undefined behavior.
+///
+/// The difference between `&mut UninitSlice` and `&mut [MaybeUninit<u8>]` is
+/// that it is possible in safe code to write uninitialized bytes to an
+/// `&mut [MaybeUninit<u8>]`, which this type prohibits.
+#[repr(transparent)]
+pub struct UninitSlice([MaybeUninit<u8>]);
+
+impl UninitSlice {
+    /// Creates a `&mut UninitSlice` wrapping a slice of initialised memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    ///
+    /// let mut buffer = [0u8; 64];
+    /// let slice = UninitSlice::new(&mut buffer[..]);
+    /// ```
+    #[inline]
+    pub fn new(slice: &mut [u8]) -> &mut UninitSlice {
+        unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
+    }
+
+    /// Creates a `&mut UninitSlice` wrapping a slice of uninitialised memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    /// use core::mem::MaybeUninit;
+    ///
+    /// let mut buffer = [MaybeUninit::uninit(); 64];
+    /// let slice = UninitSlice::uninit(&mut buffer[..]);
+    ///
+    /// let mut vec = Vec::with_capacity(1024);
+    /// let spare: &mut UninitSlice = vec.spare_capacity_mut().into();
+    /// ```
+    #[inline]
+    pub fn uninit(slice: &mut [MaybeUninit<u8>]) -> &mut UninitSlice {
+        unsafe { &mut *(slice as *mut [MaybeUninit<u8>] as *mut UninitSlice) }
+    }
+
+    fn uninit_ref(slice: &[MaybeUninit<u8>]) -> &UninitSlice {
+        unsafe { &*(slice as *const [MaybeUninit<u8>] as *const UninitSlice) }
+    }
+
+    /// Create a `&mut UninitSlice` from a pointer and a length.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that `ptr` references a valid memory region owned
+    /// by the caller representing a byte slice for the duration of `'a`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    ///
+    /// let bytes = b"hello world".to_vec();
+    /// let ptr = bytes.as_ptr() as *mut _;
+    /// let len = bytes.len();
+    ///
+    /// let slice = unsafe { UninitSlice::from_raw_parts_mut(ptr, len) };
+    /// ```
+    #[inline]
+    pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut UninitSlice {
+        let maybe_init: &mut [MaybeUninit<u8>] =
+            core::slice::from_raw_parts_mut(ptr as *mut _, len);
+        Self::uninit(maybe_init)
+    }
+
+    /// Write a single byte at the specified offset.
+    ///
+    /// # Panics
+    ///
+    /// The function panics if `index` is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    ///
+    /// let mut data = [b'f', b'o', b'o'];
+    /// let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
+    ///
+    /// slice.write_byte(0, b'b');
+    ///
+    /// assert_eq!(b"boo", &data[..]);
+    /// ```
+    #[inline]
+    pub fn write_byte(&mut self, index: usize, byte: u8) {
+        assert!(index < self.len());
+
+        unsafe { self[index..].as_mut_ptr().write(byte) }
+    }
+
+    /// Copies bytes  from `src` into `self`.
+    ///
+    /// The length of `src` must be the same as `self`.
+    ///
+    /// # Panics
+    ///
+    /// The function panics if `src` has a different length than `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::buf::UninitSlice;
+    ///
+    /// let mut data = [b'f', b'o', b'o'];
+    /// let slice = unsafe { UninitSlice::from_raw_parts_mut(data.as_mut_ptr(), 3) };
+    ///
+    /// slice.copy_from_slice(b"bar");
+    ///
+    /// assert_eq!(b"bar", &data[..]);
+    /// ```
+    #[inline]
+    pub fn copy_from_slice(&mut self, src: &[u8]) {
+        use core::ptr;
+
+        assert_eq!(self.len(), src.len());
+
+        unsafe {
+            ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
+        }
+    }
+
+    /// Return a raw pointer to the slice's buffer.
+    ///
+    /// # Safety
+    ///
+    /// The caller **must not** read from the referenced memory and **must not**
+    /// write **uninitialized** bytes to the slice either.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut data = [0, 1, 2];
+    /// let mut slice = &mut data[..];
+    /// let ptr = BufMut::chunk_mut(&mut slice).as_mut_ptr();
+    /// ```
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut u8 {
+        self.0.as_mut_ptr() as *mut _
+    }
+
+    /// Return a `&mut [MaybeUninit<u8>]` to this slice's buffer.
+    ///
+    /// # Safety
+    ///
+    /// The caller **must not** read from the referenced memory and **must not** write
+    /// **uninitialized** bytes to the slice either. This is because `BufMut` implementation
+    /// that created the `UninitSlice` knows which parts are initialized. Writing uninitialized
+    /// bytes to the slice may cause the `BufMut` to read those bytes and trigger undefined
+    /// behavior.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut data = [0, 1, 2];
+    /// let mut slice = &mut data[..];
+    /// unsafe {
+    ///     let uninit_slice = BufMut::chunk_mut(&mut slice).as_uninit_slice_mut();
+    /// };
+    /// ```
+    #[inline]
+    pub unsafe fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+        &mut self.0
+    }
+
+    /// Returns the number of bytes in the slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BufMut;
+    ///
+    /// let mut data = [0, 1, 2];
+    /// let mut slice = &mut data[..];
+    /// let len = BufMut::chunk_mut(&mut slice).len();
+    ///
+    /// assert_eq!(len, 3);
+    /// ```
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.0.len()
+    }
+}
+
+impl fmt::Debug for UninitSlice {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("UninitSlice[...]").finish()
+    }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut UninitSlice {
+    fn from(slice: &'a mut [u8]) -> Self {
+        UninitSlice::new(slice)
+    }
+}
+
+impl<'a> From<&'a mut [MaybeUninit<u8>]> for &'a mut UninitSlice {
+    fn from(slice: &'a mut [MaybeUninit<u8>]) -> Self {
+        UninitSlice::uninit(slice)
+    }
+}
+
+macro_rules! impl_index {
+    ($($t:ty),*) => {
+        $(
+            impl Index<$t> for UninitSlice {
+                type Output = UninitSlice;
+
+                #[inline]
+                fn index(&self, index: $t) -> &UninitSlice {
+                    UninitSlice::uninit_ref(&self.0[index])
+                }
+            }
+
+            impl IndexMut<$t> for UninitSlice {
+                #[inline]
+                fn index_mut(&mut self, index: $t) -> &mut UninitSlice {
+                    UninitSlice::uninit(&mut self.0[index])
+                }
+            }
+        )*
+    };
+}
+
+impl_index!(
+    Range<usize>,
+    RangeFrom<usize>,
+    RangeFull,
+    RangeInclusive<usize>,
+    RangeTo<usize>,
+    RangeToInclusive<usize>
+);
+
+
\ No newline at end of file diff --git a/src/bytes/buf/vec_deque.rs.html b/src/bytes/buf/vec_deque.rs.html new file mode 100644 index 000000000..a276b6f8f --- /dev/null +++ b/src/bytes/buf/vec_deque.rs.html @@ -0,0 +1,46 @@ +vec_deque.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+
use alloc::collections::VecDeque;
+
+use super::Buf;
+
+impl Buf for VecDeque<u8> {
+    fn remaining(&self) -> usize {
+        self.len()
+    }
+
+    fn chunk(&self) -> &[u8] {
+        let (s1, s2) = self.as_slices();
+        if s1.is_empty() {
+            s2
+        } else {
+            s1
+        }
+    }
+
+    fn advance(&mut self, cnt: usize) {
+        self.drain(..cnt);
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/buf/writer.rs.html b/src/bytes/buf/writer.rs.html new file mode 100644 index 000000000..25aa759d1 --- /dev/null +++ b/src/bytes/buf/writer.rs.html @@ -0,0 +1,178 @@ +writer.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+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()`](BufMut::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::BufMut;
+    ///
+    /// let 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::BufMut;
+    ///
+    /// 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::BufMut;
+    /// 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(())
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/bytes.rs.html b/src/bytes/bytes.rs.html new file mode 100644 index 000000000..e347c1a5a --- /dev/null +++ b/src/bytes/bytes.rs.html @@ -0,0 +1,2696 @@ +bytes.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+
use core::iter::FromIterator;
+use core::mem::{self, ManuallyDrop};
+use core::ops::{Deref, RangeBounds};
+use core::{cmp, fmt, hash, ptr, slice, usize};
+
+use alloc::{
+    alloc::{dealloc, Layout},
+    borrow::Borrow,
+    boxed::Box,
+    string::String,
+    vec::Vec,
+};
+
+use crate::buf::IntoIter;
+#[allow(unused)]
+use crate::loom::sync::atomic::AtomicMut;
+use crate::loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
+use crate::Buf;
+
+/// 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::Bytes;
+///
+/// let mut mem = Bytes::from("Hello world");
+/// let a = mem.slice(0..5);
+///
+/// assert_eq!(a, "Hello");
+///
+/// let b = mem.split_to(6);
+///
+/// assert_eq!(mem, "world");
+/// assert_eq!(b, "Hello ");
+/// ```
+///
+/// # 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:
+///
+/// ```text
+///
+///    Arc ptrs                   ┌─────────┐
+///    ________________________ / │ Bytes 2 │
+///   /                           └─────────┘
+///  /          ┌───────────┐     |         |
+/// |_________/ │  Bytes 1  │     |         |
+/// |           └───────────┘     |         |
+/// |           |           | ___/ data     | tail
+/// |      data |      tail |/              |
+/// v           v           v               v
+/// ┌─────┬─────┬───────────┬───────────────┬─────┐
+/// │ Arc │     │           │               │     │
+/// └─────┴─────┴───────────┴───────────────┴─────┘
+/// ```
+pub struct Bytes {
+    ptr: *const u8,
+    len: usize,
+    // inlined "trait object"
+    data: AtomicPtr<()>,
+    vtable: &'static Vtable,
+}
+
+pub(crate) struct Vtable {
+    /// fn(data, ptr, len)
+    pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,
+    /// fn(data, ptr, len)
+    ///
+    /// takes `Bytes` to value
+    pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec<u8>,
+    /// fn(data)
+    pub is_unique: unsafe fn(&AtomicPtr<()>) -> bool,
+    /// fn(data, ptr, len)
+    pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
+}
+
+impl Bytes {
+    /// Creates a new empty `Bytes`.
+    ///
+    /// This will not allocate and the returned `Bytes` handle will be empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let b = Bytes::new();
+    /// assert_eq!(&b[..], b"");
+    /// ```
+    #[inline]
+    #[cfg(not(all(loom, test)))]
+    pub const fn new() -> Self {
+        // Make it a named const to work around
+        // "unsizing casts are not allowed in const fn"
+        const EMPTY: &[u8] = &[];
+        Bytes::from_static(EMPTY)
+    }
+
+    #[cfg(all(loom, test))]
+    pub fn new() -> Self {
+        const EMPTY: &[u8] = &[];
+        Bytes::from_static(EMPTY)
+    }
+
+    /// Creates a new `Bytes` from a static slice.
+    ///
+    /// The returned `Bytes` will point directly to the static slice. There is
+    /// no allocating or copying.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let b = Bytes::from_static(b"hello");
+    /// assert_eq!(&b[..], b"hello");
+    /// ```
+    #[inline]
+    #[cfg(not(all(loom, test)))]
+    pub const fn from_static(bytes: &'static [u8]) -> Self {
+        Bytes {
+            ptr: bytes.as_ptr(),
+            len: bytes.len(),
+            data: AtomicPtr::new(ptr::null_mut()),
+            vtable: &STATIC_VTABLE,
+        }
+    }
+
+    #[cfg(all(loom, test))]
+    pub fn from_static(bytes: &'static [u8]) -> Self {
+        Bytes {
+            ptr: bytes.as_ptr(),
+            len: bytes.len(),
+            data: AtomicPtr::new(ptr::null_mut()),
+            vtable: &STATIC_VTABLE,
+        }
+    }
+
+    /// Returns the number of bytes contained in this `Bytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let b = Bytes::from(&b"hello"[..]);
+    /// assert_eq!(b.len(), 5);
+    /// ```
+    #[inline]
+    pub const fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns true if the `Bytes` has a length of 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let b = Bytes::new();
+    /// assert!(b.is_empty());
+    /// ```
+    #[inline]
+    pub const fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    /// Returns true if this is the only reference to the data.
+    ///
+    /// Always returns false if the data is backed by a static slice.
+    ///
+    /// 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::Bytes;
+    ///
+    /// let a = Bytes::from(vec![1, 2, 3]);
+    /// assert!(a.is_unique());
+    /// let b = a.clone();
+    /// assert!(!a.is_unique());
+    /// ```
+    pub fn is_unique(&self) -> bool {
+        unsafe { (self.vtable.is_unique)(&self.data) }
+    }
+
+    /// Creates `Bytes` instance from slice, by copying it.
+    pub fn copy_from_slice(data: &[u8]) -> Self {
+        data.to_vec().into()
+    }
+
+    /// Returns a slice of self for the provided range.
+    ///
+    /// This will increment the reference count for the underlying memory and
+    /// return a new `Bytes` handle set to the slice.
+    ///
+    /// This operation is `O(1)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let a = Bytes::from(&b"hello world"[..]);
+    /// let b = a.slice(2..5);
+    ///
+    /// assert_eq!(&b[..], b"llo");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
+    /// will panic.
+    pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
+        use core::ops::Bound;
+
+        let len = self.len();
+
+        let begin = match range.start_bound() {
+            Bound::Included(&n) => n,
+            Bound::Excluded(&n) => n.checked_add(1).expect("out of range"),
+            Bound::Unbounded => 0,
+        };
+
+        let end = match range.end_bound() {
+            Bound::Included(&n) => n.checked_add(1).expect("out of range"),
+            Bound::Excluded(&n) => n,
+            Bound::Unbounded => len,
+        };
+
+        assert!(
+            begin <= end,
+            "range start must not be greater than end: {:?} <= {:?}",
+            begin,
+            end,
+        );
+        assert!(
+            end <= len,
+            "range end out of bounds: {:?} <= {:?}",
+            end,
+            len,
+        );
+
+        if end == begin {
+            return Bytes::new();
+        }
+
+        let mut ret = self.clone();
+
+        ret.len = end - begin;
+        ret.ptr = unsafe { ret.ptr.add(begin) };
+
+        ret
+    }
+
+    /// Returns a slice of self that is equivalent to the given `subset`.
+    ///
+    /// When processing a `Bytes` buffer with other tools, one often gets a
+    /// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it.
+    /// This function turns that `&[u8]` into another `Bytes`, as if one had
+    /// called `self.slice()` with the offsets that correspond to `subset`.
+    ///
+    /// This operation is `O(1)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let bytes = Bytes::from(&b"012345678"[..]);
+    /// let as_slice = bytes.as_ref();
+    /// let subset = &as_slice[2..6];
+    /// let subslice = bytes.slice_ref(&subset);
+    /// assert_eq!(&subslice[..], b"2345");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Requires that the given `sub` slice is in fact contained within the
+    /// `Bytes` buffer; otherwise this function will panic.
+    pub fn slice_ref(&self, subset: &[u8]) -> Self {
+        // Empty slice and empty Bytes may have their pointers reset
+        // so explicitly allow empty slice to be a subslice of any slice.
+        if subset.is_empty() {
+            return Bytes::new();
+        }
+
+        let bytes_p = self.as_ptr() as usize;
+        let bytes_len = self.len();
+
+        let sub_p = subset.as_ptr() as usize;
+        let sub_len = subset.len();
+
+        assert!(
+            sub_p >= bytes_p,
+            "subset pointer ({:p}) is smaller than self pointer ({:p})",
+            subset.as_ptr(),
+            self.as_ptr(),
+        );
+        assert!(
+            sub_p + sub_len <= bytes_p + bytes_len,
+            "subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})",
+            self.as_ptr(),
+            bytes_len,
+            subset.as_ptr(),
+            sub_len,
+        );
+
+        let sub_offset = sub_p - bytes_p;
+
+        self.slice(sub_offset..(sub_offset + sub_len))
+    }
+
+    /// Splits the bytes into two at the given index.
+    ///
+    /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
+    /// contains elements `[at, len)`.
+    ///
+    /// This is an `O(1)` operation that just increases the reference count and
+    /// sets a few indices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let mut a = Bytes::from(&b"hello world"[..]);
+    /// let b = a.split_off(5);
+    ///
+    /// assert_eq!(&a[..], b"hello");
+    /// assert_eq!(&b[..], b" world");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > len`.
+    #[must_use = "consider Bytes::truncate if you don't need the other half"]
+    pub fn split_off(&mut self, at: usize) -> Self {
+        if at == self.len() {
+            return Bytes::new();
+        }
+
+        if at == 0 {
+            return mem::replace(self, Bytes::new());
+        }
+
+        assert!(
+            at <= self.len(),
+            "split_off out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
+
+        let mut ret = self.clone();
+
+        self.len = at;
+
+        unsafe { ret.inc_start(at) };
+
+        ret
+    }
+
+    /// Splits the bytes into two at the given index.
+    ///
+    /// Afterwards `self` contains elements `[at, len)`, and the returned
+    /// `Bytes` contains elements `[0, at)`.
+    ///
+    /// This is an `O(1)` operation that just increases the reference count and
+    /// sets a few indices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let mut a = Bytes::from(&b"hello world"[..]);
+    /// let b = a.split_to(5);
+    ///
+    /// assert_eq!(&a[..], b" world");
+    /// assert_eq!(&b[..], b"hello");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > len`.
+    #[must_use = "consider Bytes::advance if you don't need the other half"]
+    pub fn split_to(&mut self, at: usize) -> Self {
+        if at == self.len() {
+            return mem::replace(self, Bytes::new());
+        }
+
+        if at == 0 {
+            return Bytes::new();
+        }
+
+        assert!(
+            at <= self.len(),
+            "split_to out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
+
+        let mut ret = self.clone();
+
+        unsafe { self.inc_start(at) };
+
+        ret.len = at;
+        ret
+    }
+
+    /// Shortens the buffer, keeping the first `len` bytes and dropping the
+    /// rest.
+    ///
+    /// If `len` is greater than the buffer's current length, this has no
+    /// effect.
+    ///
+    /// The [split_off](`Self::split_off()`) method can emulate `truncate`, but this causes the
+    /// excess bytes to be returned instead of dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let mut buf = Bytes::from(&b"hello world"[..]);
+    /// buf.truncate(5);
+    /// assert_eq!(buf, b"hello"[..]);
+    /// ```
+    #[inline]
+    pub fn truncate(&mut self, len: usize) {
+        if len < self.len {
+            // The Vec "promotable" vtables do not store the capacity,
+            // so we cannot truncate while using this repr. We *have* to
+            // promote using `split_off` so the capacity can be stored.
+            if self.vtable as *const Vtable == &PROMOTABLE_EVEN_VTABLE
+                || self.vtable as *const Vtable == &PROMOTABLE_ODD_VTABLE
+            {
+                drop(self.split_off(len));
+            } else {
+                self.len = len;
+            }
+        }
+    }
+
+    /// Clears the buffer, removing all data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::Bytes;
+    ///
+    /// let mut buf = Bytes::from(&b"hello world"[..]);
+    /// buf.clear();
+    /// assert!(buf.is_empty());
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) {
+        self.truncate(0);
+    }
+
+    #[inline]
+    pub(crate) unsafe fn with_vtable(
+        ptr: *const u8,
+        len: usize,
+        data: AtomicPtr<()>,
+        vtable: &'static Vtable,
+    ) -> Bytes {
+        Bytes {
+            ptr,
+            len,
+            data,
+            vtable,
+        }
+    }
+
+    // private
+
+    #[inline]
+    fn as_slice(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.ptr, self.len) }
+    }
+
+    #[inline]
+    unsafe fn inc_start(&mut self, by: usize) {
+        // should already be asserted, but debug assert for tests
+        debug_assert!(self.len >= by, "internal: inc_start out of bounds");
+        self.len -= by;
+        self.ptr = self.ptr.add(by);
+    }
+}
+
+// Vtable must enforce this behavior
+unsafe impl Send for Bytes {}
+unsafe impl Sync for Bytes {}
+
+impl Drop for Bytes {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe { (self.vtable.drop)(&mut self.data, self.ptr, self.len) }
+    }
+}
+
+impl Clone for Bytes {
+    #[inline]
+    fn clone(&self) -> Bytes {
+        unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
+    }
+}
+
+impl Buf for Bytes {
+    #[inline]
+    fn remaining(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk(&self) -> &[u8] {
+        self.as_slice()
+    }
+
+    #[inline]
+    fn advance(&mut self, cnt: usize) {
+        assert!(
+            cnt <= self.len(),
+            "cannot advance past `remaining`: {:?} <= {:?}",
+            cnt,
+            self.len(),
+        );
+
+        unsafe {
+            self.inc_start(cnt);
+        }
+    }
+
+    fn copy_to_bytes(&mut self, len: usize) -> Self {
+        self.split_to(len)
+    }
+}
+
+impl Deref for Bytes {
+    type Target = [u8];
+
+    #[inline]
+    fn deref(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl AsRef<[u8]> for Bytes {
+    #[inline]
+    fn as_ref(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl hash::Hash for Bytes {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: hash::Hasher,
+    {
+        self.as_slice().hash(state);
+    }
+}
+
+impl Borrow<[u8]> for Bytes {
+    fn borrow(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl IntoIterator for Bytes {
+    type Item = u8;
+    type IntoIter = IntoIter<Bytes>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter::new(self)
+    }
+}
+
+impl<'a> IntoIterator for &'a Bytes {
+    type Item = &'a u8;
+    type IntoIter = core::slice::Iter<'a, u8>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.as_slice().iter()
+    }
+}
+
+impl FromIterator<u8> for Bytes {
+    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
+        Vec::from_iter(into_iter).into()
+    }
+}
+
+// impl Eq
+
+impl PartialEq for Bytes {
+    fn eq(&self, other: &Bytes) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl PartialOrd for Bytes {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(other.as_slice())
+    }
+}
+
+impl Ord for Bytes {
+    fn cmp(&self, other: &Bytes) -> cmp::Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
+}
+
+impl Eq for Bytes {}
+
+impl PartialEq<[u8]> for Bytes {
+    fn eq(&self, other: &[u8]) -> bool {
+        self.as_slice() == other
+    }
+}
+
+impl PartialOrd<[u8]> for Bytes {
+    fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(other)
+    }
+}
+
+impl PartialEq<Bytes> for [u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for [u8] {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
+    }
+}
+
+impl PartialEq<str> for Bytes {
+    fn eq(&self, other: &str) -> bool {
+        self.as_slice() == other.as_bytes()
+    }
+}
+
+impl PartialOrd<str> for Bytes {
+    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(other.as_bytes())
+    }
+}
+
+impl PartialEq<Bytes> for str {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for str {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
+    }
+}
+
+impl PartialEq<Vec<u8>> for Bytes {
+    fn eq(&self, other: &Vec<u8>) -> bool {
+        *self == other[..]
+    }
+}
+
+impl PartialOrd<Vec<u8>> for Bytes {
+    fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(&other[..])
+    }
+}
+
+impl PartialEq<Bytes> for Vec<u8> {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for Vec<u8> {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
+    }
+}
+
+impl PartialEq<String> for Bytes {
+    fn eq(&self, other: &String) -> bool {
+        *self == other[..]
+    }
+}
+
+impl PartialOrd<String> for Bytes {
+    fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(other.as_bytes())
+    }
+}
+
+impl PartialEq<Bytes> for String {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for String {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
+    }
+}
+
+impl PartialEq<Bytes> for &[u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for &[u8] {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
+    }
+}
+
+impl PartialEq<Bytes> for &str {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<Bytes> for &str {
+    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
+    }
+}
+
+impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
+where
+    Bytes: PartialEq<T>,
+{
+    fn eq(&self, other: &&'a T) -> bool {
+        *self == **other
+    }
+}
+
+impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
+where
+    Bytes: PartialOrd<T>,
+{
+    fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
+        self.partial_cmp(&**other)
+    }
+}
+
+// impl From
+
+impl Default for Bytes {
+    #[inline]
+    fn default() -> Bytes {
+        Bytes::new()
+    }
+}
+
+impl From<&'static [u8]> for Bytes {
+    fn from(slice: &'static [u8]) -> Bytes {
+        Bytes::from_static(slice)
+    }
+}
+
+impl From<&'static str> for Bytes {
+    fn from(slice: &'static str) -> Bytes {
+        Bytes::from_static(slice.as_bytes())
+    }
+}
+
+impl From<Vec<u8>> for Bytes {
+    fn from(vec: Vec<u8>) -> Bytes {
+        let mut vec = ManuallyDrop::new(vec);
+        let ptr = vec.as_mut_ptr();
+        let len = vec.len();
+        let cap = vec.capacity();
+
+        // Avoid an extra allocation if possible.
+        if len == cap {
+            let vec = ManuallyDrop::into_inner(vec);
+            return Bytes::from(vec.into_boxed_slice());
+        }
+
+        let shared = Box::new(Shared {
+            buf: ptr,
+            cap,
+            ref_cnt: AtomicUsize::new(1),
+        });
+
+        let shared = Box::into_raw(shared);
+        // The pointer should be aligned, so this assert should
+        // always succeed.
+        debug_assert!(
+            0 == (shared as usize & KIND_MASK),
+            "internal: Box<Shared> should have an aligned pointer",
+        );
+        Bytes {
+            ptr,
+            len,
+            data: AtomicPtr::new(shared as _),
+            vtable: &SHARED_VTABLE,
+        }
+    }
+}
+
+impl From<Box<[u8]>> for Bytes {
+    fn from(slice: Box<[u8]>) -> Bytes {
+        // Box<[u8]> doesn't contain a heap allocation for empty slices,
+        // so the pointer isn't aligned enough for the KIND_VEC stashing to
+        // work.
+        if slice.is_empty() {
+            return Bytes::new();
+        }
+
+        let len = slice.len();
+        let ptr = Box::into_raw(slice) as *mut u8;
+
+        if ptr as usize & 0x1 == 0 {
+            let data = ptr_map(ptr, |addr| addr | KIND_VEC);
+            Bytes {
+                ptr,
+                len,
+                data: AtomicPtr::new(data.cast()),
+                vtable: &PROMOTABLE_EVEN_VTABLE,
+            }
+        } else {
+            Bytes {
+                ptr,
+                len,
+                data: AtomicPtr::new(ptr.cast()),
+                vtable: &PROMOTABLE_ODD_VTABLE,
+            }
+        }
+    }
+}
+
+impl From<String> for Bytes {
+    fn from(s: String) -> Bytes {
+        Bytes::from(s.into_bytes())
+    }
+}
+
+impl From<Bytes> for Vec<u8> {
+    fn from(bytes: Bytes) -> Vec<u8> {
+        let bytes = ManuallyDrop::new(bytes);
+        unsafe { (bytes.vtable.to_vec)(&bytes.data, bytes.ptr, bytes.len) }
+    }
+}
+
+// ===== impl Vtable =====
+
+impl fmt::Debug for Vtable {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Vtable")
+            .field("clone", &(self.clone as *const ()))
+            .field("drop", &(self.drop as *const ()))
+            .finish()
+    }
+}
+
+// ===== impl StaticVtable =====
+
+const STATIC_VTABLE: Vtable = Vtable {
+    clone: static_clone,
+    to_vec: static_to_vec,
+    is_unique: static_is_unique,
+    drop: static_drop,
+};
+
+unsafe fn static_clone(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let slice = slice::from_raw_parts(ptr, len);
+    Bytes::from_static(slice)
+}
+
+unsafe fn static_to_vec(_: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
+    let slice = slice::from_raw_parts(ptr, len);
+    slice.to_vec()
+}
+
+fn static_is_unique(_: &AtomicPtr<()>) -> bool {
+    false
+}
+
+unsafe fn static_drop(_: &mut AtomicPtr<()>, _: *const u8, _: usize) {
+    // nothing to drop for &'static [u8]
+}
+
+// ===== impl PromotableVtable =====
+
+static PROMOTABLE_EVEN_VTABLE: Vtable = Vtable {
+    clone: promotable_even_clone,
+    to_vec: promotable_even_to_vec,
+    is_unique: promotable_is_unique,
+    drop: promotable_even_drop,
+};
+
+static PROMOTABLE_ODD_VTABLE: Vtable = Vtable {
+    clone: promotable_odd_clone,
+    to_vec: promotable_odd_to_vec,
+    is_unique: promotable_is_unique,
+    drop: promotable_odd_drop,
+};
+
+unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Acquire);
+    let kind = shared as usize & KIND_MASK;
+
+    if kind == KIND_ARC {
+        shallow_clone_arc(shared.cast(), ptr, len)
+    } else {
+        debug_assert_eq!(kind, KIND_VEC);
+        let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
+        shallow_clone_vec(data, shared, buf, ptr, len)
+    }
+}
+
+unsafe fn promotable_to_vec(
+    data: &AtomicPtr<()>,
+    ptr: *const u8,
+    len: usize,
+    f: fn(*mut ()) -> *mut u8,
+) -> Vec<u8> {
+    let shared = data.load(Ordering::Acquire);
+    let kind = shared as usize & KIND_MASK;
+
+    if kind == KIND_ARC {
+        shared_to_vec_impl(shared.cast(), ptr, len)
+    } else {
+        // If Bytes holds a Vec, then the offset must be 0.
+        debug_assert_eq!(kind, KIND_VEC);
+
+        let buf = f(shared);
+
+        let cap = (ptr as usize - buf as usize) + len;
+
+        // Copy back buffer
+        ptr::copy(ptr, buf, len);
+
+        Vec::from_raw_parts(buf, len, cap)
+    }
+}
+
+unsafe fn promotable_even_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
+    promotable_to_vec(data, ptr, len, |shared| {
+        ptr_map(shared.cast(), |addr| addr & !KIND_MASK)
+    })
+}
+
+unsafe fn promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
+    data.with_mut(|shared| {
+        let shared = *shared;
+        let kind = shared as usize & KIND_MASK;
+
+        if kind == KIND_ARC {
+            release_shared(shared.cast());
+        } else {
+            debug_assert_eq!(kind, KIND_VEC);
+            let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
+            free_boxed_slice(buf, ptr, len);
+        }
+    });
+}
+
+unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Acquire);
+    let kind = shared as usize & KIND_MASK;
+
+    if kind == KIND_ARC {
+        shallow_clone_arc(shared as _, ptr, len)
+    } else {
+        debug_assert_eq!(kind, KIND_VEC);
+        shallow_clone_vec(data, shared, shared.cast(), ptr, len)
+    }
+}
+
+unsafe fn promotable_odd_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
+    promotable_to_vec(data, ptr, len, |shared| shared.cast())
+}
+
+unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
+    data.with_mut(|shared| {
+        let shared = *shared;
+        let kind = shared as usize & KIND_MASK;
+
+        if kind == KIND_ARC {
+            release_shared(shared.cast());
+        } else {
+            debug_assert_eq!(kind, KIND_VEC);
+
+            free_boxed_slice(shared.cast(), ptr, len);
+        }
+    });
+}
+
+unsafe fn promotable_is_unique(data: &AtomicPtr<()>) -> bool {
+    let shared = data.load(Ordering::Acquire);
+    let kind = shared as usize & KIND_MASK;
+
+    if kind == KIND_ARC {
+        let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
+        ref_cnt == 1
+    } else {
+        true
+    }
+}
+
+unsafe fn free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) {
+    let cap = (offset as usize - buf as usize) + len;
+    dealloc(buf, Layout::from_size_align(cap, 1).unwrap())
+}
+
+// ===== impl SharedVtable =====
+
+struct Shared {
+    // Holds arguments to dealloc upon Drop, but otherwise doesn't use them
+    buf: *mut u8,
+    cap: usize,
+    ref_cnt: AtomicUsize,
+}
+
+impl Drop for Shared {
+    fn drop(&mut self) {
+        unsafe { dealloc(self.buf, Layout::from_size_align(self.cap, 1).unwrap()) }
+    }
+}
+
+// Assert that the alignment of `Shared` is divisible by 2.
+// This is a necessary invariant since we depend on allocating `Shared` a
+// shared object to implicitly carry the `KIND_ARC` flag in its pointer.
+// This flag is set when the LSB is 0.
+const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; // Assert that the alignment of `Shared` is divisible by 2.
+
+static SHARED_VTABLE: Vtable = Vtable {
+    clone: shared_clone,
+    to_vec: shared_to_vec,
+    is_unique: shared_is_unique,
+    drop: shared_drop,
+};
+
+const KIND_ARC: usize = 0b0;
+const KIND_VEC: usize = 0b1;
+const KIND_MASK: usize = 0b1;
+
+unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Relaxed);
+    shallow_clone_arc(shared as _, ptr, len)
+}
+
+unsafe fn shared_to_vec_impl(shared: *mut Shared, ptr: *const u8, len: usize) -> Vec<u8> {
+    // Check that the ref_cnt is 1 (unique).
+    //
+    // If it is unique, then it is set to 0 with AcqRel fence for the same
+    // reason in release_shared.
+    //
+    // Otherwise, we take the other branch and call release_shared.
+    if (*shared)
+        .ref_cnt
+        .compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed)
+        .is_ok()
+    {
+        // Deallocate the `Shared` instance without running its destructor.
+        let shared = *Box::from_raw(shared);
+        let shared = ManuallyDrop::new(shared);
+        let buf = shared.buf;
+        let cap = shared.cap;
+
+        // Copy back buffer
+        ptr::copy(ptr, buf, len);
+
+        Vec::from_raw_parts(buf, len, cap)
+    } else {
+        let v = slice::from_raw_parts(ptr, len).to_vec();
+        release_shared(shared);
+        v
+    }
+}
+
+unsafe fn shared_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
+    shared_to_vec_impl(data.load(Ordering::Relaxed).cast(), ptr, len)
+}
+
+pub(crate) unsafe fn shared_is_unique(data: &AtomicPtr<()>) -> bool {
+    let shared = data.load(Ordering::Acquire);
+    let ref_cnt = (*shared.cast::<Shared>()).ref_cnt.load(Ordering::Relaxed);
+    ref_cnt == 1
+}
+
+unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
+    data.with_mut(|shared| {
+        release_shared(shared.cast());
+    });
+}
+
+unsafe fn shallow_clone_arc(shared: *mut Shared, ptr: *const u8, len: usize) -> Bytes {
+    let old_size = (*shared).ref_cnt.fetch_add(1, Ordering::Relaxed);
+
+    if old_size > usize::MAX >> 1 {
+        crate::abort();
+    }
+
+    Bytes {
+        ptr,
+        len,
+        data: AtomicPtr::new(shared as _),
+        vtable: &SHARED_VTABLE,
+    }
+}
+
+#[cold]
+unsafe fn shallow_clone_vec(
+    atom: &AtomicPtr<()>,
+    ptr: *const (),
+    buf: *mut u8,
+    offset: *const u8,
+    len: usize,
+) -> Bytes {
+    // If  the buffer is still tracked in a `Vec<u8>`. It is time to
+    // promote the vec to an `Arc`. This could potentially be called
+    // concurrently, so some care must be taken.
+
+    // First, allocate a new `Shared` instance containing the
+    // `Vec` fields. It's important to note that `ptr`, `len`,
+    // and `cap` cannot be mutated without having `&mut self`.
+    // This means that these fields will not be concurrently
+    // updated and since the buffer hasn't been promoted to an
+    // `Arc`, those three fields still are the components of the
+    // vector.
+    let shared = Box::new(Shared {
+        buf,
+        cap: (offset as usize - buf as usize) + len,
+        // Initialize refcount to 2. One for this reference, and one
+        // for the new clone that will be returned from
+        // `shallow_clone`.
+        ref_cnt: AtomicUsize::new(2),
+    });
+
+    let shared = Box::into_raw(shared);
+
+    // The pointer should be aligned, so this assert should
+    // always succeed.
+    debug_assert!(
+        0 == (shared as usize & KIND_MASK),
+        "internal: Box<Shared> should have an aligned pointer",
+    );
+
+    // Try compare & swapping the pointer into the `arc` field.
+    // `Release` is used synchronize with other threads that
+    // will load the `arc` field.
+    //
+    // If the `compare_exchange` fails, then the thread lost the
+    // race to promote the buffer to shared. The `Acquire`
+    // ordering will synchronize with the `compare_exchange`
+    // that happened in the other thread and the `Shared`
+    // pointed to by `actual` will be visible.
+    match atom.compare_exchange(ptr as _, shared as _, Ordering::AcqRel, Ordering::Acquire) {
+        Ok(actual) => {
+            debug_assert!(actual as usize == ptr as usize);
+            // The upgrade was successful, the new handle can be
+            // returned.
+            Bytes {
+                ptr: offset,
+                len,
+                data: AtomicPtr::new(shared as _),
+                vtable: &SHARED_VTABLE,
+            }
+        }
+        Err(actual) => {
+            // The upgrade failed, a concurrent clone happened. Release
+            // the allocation that was made in this thread, it will not
+            // be needed.
+            let shared = Box::from_raw(shared);
+            mem::forget(*shared);
+
+            // Buffer already promoted to shared storage, so increment ref
+            // count.
+            shallow_clone_arc(actual as _, offset, len)
+        }
+    }
+}
+
+unsafe fn release_shared(ptr: *mut Shared) {
+    // `Shared` storage... follow the drop steps from Arc.
+    if (*ptr).ref_cnt.fetch_sub(1, Ordering::Release) != 1 {
+        return;
+    }
+
+    // This fence is needed to prevent reordering of use of the data and
+    // deletion of the data.  Because it is marked `Release`, the decreasing
+    // of the reference count synchronizes with this `Acquire` fence. This
+    // means that use of the data happens before decreasing the reference
+    // count, which happens before this fence, which happens before the
+    // deletion of the data.
+    //
+    // As explained in the [Boost documentation][1],
+    //
+    // > It is important to enforce any possible access to the object in one
+    // > thread (through an existing reference) to *happen before* deleting
+    // > the object in a different thread. This is achieved by a "release"
+    // > operation after dropping a reference (any access to the object
+    // > through this reference must obviously happened before), and an
+    // > "acquire" operation before deleting the object.
+    //
+    // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
+    //
+    // Thread sanitizer does not support atomic fences. Use an atomic load
+    // instead.
+    (*ptr).ref_cnt.load(Ordering::Acquire);
+
+    // Drop the data
+    drop(Box::from_raw(ptr));
+}
+
+// Ideally we would always use this version of `ptr_map` since it is strict
+// provenance compatible, but it results in worse codegen. We will however still
+// use it on miri because it gives better diagnostics for people who test bytes
+// code with miri.
+//
+// See https://github.com/tokio-rs/bytes/pull/545 for more info.
+#[cfg(miri)]
+fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
+where
+    F: FnOnce(usize) -> usize,
+{
+    let old_addr = ptr as usize;
+    let new_addr = f(old_addr);
+    let diff = new_addr.wrapping_sub(old_addr);
+    ptr.wrapping_add(diff)
+}
+
+#[cfg(not(miri))]
+fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
+where
+    F: FnOnce(usize) -> usize,
+{
+    let old_addr = ptr as usize;
+    let new_addr = f(old_addr);
+    new_addr as *mut u8
+}
+
+// compile-fails
+
+/// ```compile_fail
+/// use bytes::Bytes;
+/// #[deny(unused_must_use)]
+/// {
+///     let mut b1 = Bytes::from("hello world");
+///     b1.split_to(6);
+/// }
+/// ```
+fn _split_to_must_use() {}
+
+/// ```compile_fail
+/// use bytes::Bytes;
+/// #[deny(unused_must_use)]
+/// {
+///     let mut b1 = Bytes::from("hello world");
+///     b1.split_off(6);
+/// }
+/// ```
+fn _split_off_must_use() {}
+
+// fuzz tests
+#[cfg(all(test, loom))]
+mod fuzz {
+    use loom::sync::Arc;
+    use loom::thread;
+
+    use super::Bytes;
+    #[test]
+    fn bytes_cloning_vec() {
+        loom::model(|| {
+            let a = Bytes::from(b"abcdefgh".to_vec());
+            let addr = a.as_ptr() as usize;
+
+            // test the Bytes::clone is Sync by putting it in an Arc
+            let a1 = Arc::new(a);
+            let a2 = a1.clone();
+
+            let t1 = thread::spawn(move || {
+                let b: Bytes = (*a1).clone();
+                assert_eq!(b.as_ptr() as usize, addr);
+            });
+
+            let t2 = thread::spawn(move || {
+                let b: Bytes = (*a2).clone();
+                assert_eq!(b.as_ptr() as usize, addr);
+            });
+
+            t1.join().unwrap();
+            t2.join().unwrap();
+        });
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/bytes_mut.rs.html b/src/bytes/bytes_mut.rs.html new file mode 100644 index 000000000..67573d653 --- /dev/null +++ b/src/bytes/bytes_mut.rs.html @@ -0,0 +1,3632 @@ +bytes_mut.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+
use core::iter::FromIterator;
+use core::mem::{self, ManuallyDrop, MaybeUninit};
+use core::ops::{Deref, DerefMut};
+use core::ptr::{self, NonNull};
+use core::{cmp, fmt, hash, isize, slice, usize};
+
+use alloc::{
+    borrow::{Borrow, BorrowMut},
+    boxed::Box,
+    string::String,
+    vec,
+    vec::Vec,
+};
+
+use crate::buf::{IntoIter, UninitSlice};
+use crate::bytes::Vtable;
+#[allow(unused)]
+use crate::loom::sync::atomic::AtomicMut;
+use crate::loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
+use crate::{Buf, BufMut, Bytes};
+
+/// A unique reference to a contiguous slice of memory.
+///
+/// `BytesMut` represents a unique view into a potentially shared memory region.
+/// Given the uniqueness guarantee, owners of `BytesMut` handles are able to
+/// mutate the memory.
+///
+/// `BytesMut` can be thought of as containing a `buf: Arc<Vec<u8>>`, an offset
+/// into `buf`, a slice length, and a guarantee that no other `BytesMut` for the
+/// same `buf` overlaps with its slice. That guarantee means that a write lock
+/// is not required.
+///
+/// # Growth
+///
+/// `BytesMut`'s `BufMut` implementation will implicitly grow its buffer as
+/// necessary. However, explicitly reserving the required space up-front before
+/// a series of inserts will be more efficient.
+///
+/// # Examples
+///
+/// ```
+/// use bytes::{BytesMut, BufMut};
+///
+/// let mut buf = BytesMut::with_capacity(64);
+///
+/// buf.put_u8(b'h');
+/// buf.put_u8(b'e');
+/// buf.put(&b"llo"[..]);
+///
+/// assert_eq!(&buf[..], b"hello");
+///
+/// // Freeze the buffer so that it can be shared
+/// let a = buf.freeze();
+///
+/// // This does not allocate, instead `b` points to the same memory.
+/// let b = a.clone();
+///
+/// assert_eq!(&a[..], b"hello");
+/// assert_eq!(&b[..], b"hello");
+/// ```
+pub struct BytesMut {
+    ptr: NonNull<u8>,
+    len: usize,
+    cap: usize,
+    data: *mut Shared,
+}
+
+// Thread-safe reference-counted container for the shared storage. This mostly
+// the same as `core::sync::Arc` but without the weak counter. The ref counting
+// fns are based on the ones found in `std`.
+//
+// The main reason to use `Shared` instead of `core::sync::Arc` is that it ends
+// up making the overall code simpler and easier to reason about. This is due to
+// some of the logic around setting `Inner::arc` and other ways the `arc` field
+// is used. Using `Arc` ended up requiring a number of funky transmutes and
+// other shenanigans to make it work.
+struct Shared {
+    vec: Vec<u8>,
+    original_capacity_repr: usize,
+    ref_count: AtomicUsize,
+}
+
+// Assert that the alignment of `Shared` is divisible by 2.
+// This is a necessary invariant since we depend on allocating `Shared` a
+// shared object to implicitly carry the `KIND_ARC` flag in its pointer.
+// This flag is set when the LSB is 0.
+const _: [(); 0 - mem::align_of::<Shared>() % 2] = []; // Assert that the alignment of `Shared` is divisible by 2.
+
+// Buffer storage strategy flags.
+const KIND_ARC: usize = 0b0;
+const KIND_VEC: usize = 0b1;
+const KIND_MASK: usize = 0b1;
+
+// The max original capacity value. Any `Bytes` allocated with a greater initial
+// capacity will default to this.
+const MAX_ORIGINAL_CAPACITY_WIDTH: usize = 17;
+// The original capacity algorithm will not take effect unless the originally
+// allocated capacity was at least 1kb in size.
+const MIN_ORIGINAL_CAPACITY_WIDTH: usize = 10;
+// The original capacity is stored in powers of 2 starting at 1kb to a max of
+// 64kb. Representing it as such requires only 3 bits of storage.
+const ORIGINAL_CAPACITY_MASK: usize = 0b11100;
+const ORIGINAL_CAPACITY_OFFSET: usize = 2;
+
+const VEC_POS_OFFSET: usize = 5;
+// When the storage is in the `Vec` representation, the pointer can be advanced
+// at most this value. This is due to the amount of storage available to track
+// the offset is usize - number of KIND bits and number of ORIGINAL_CAPACITY
+// bits.
+const MAX_VEC_POS: usize = usize::MAX >> VEC_POS_OFFSET;
+const NOT_VEC_POS_MASK: usize = 0b11111;
+
+#[cfg(target_pointer_width = "64")]
+const PTR_WIDTH: usize = 64;
+#[cfg(target_pointer_width = "32")]
+const PTR_WIDTH: usize = 32;
+
+/*
+ *
+ * ===== BytesMut =====
+ *
+ */
+
+impl BytesMut {
+    /// Creates a new `BytesMut` with the specified capacity.
+    ///
+    /// The returned `BytesMut` will be able to hold at least `capacity` bytes
+    /// without reallocating.
+    ///
+    /// It is important to note that this function does not specify the length
+    /// of the returned `BytesMut`, but only the capacity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    ///
+    /// let mut bytes = BytesMut::with_capacity(64);
+    ///
+    /// // `bytes` contains no data, even though there is capacity
+    /// assert_eq!(bytes.len(), 0);
+    ///
+    /// bytes.put(&b"hello world"[..]);
+    ///
+    /// assert_eq!(&bytes[..], b"hello world");
+    /// ```
+    #[inline]
+    pub fn with_capacity(capacity: usize) -> BytesMut {
+        BytesMut::from_vec(Vec::with_capacity(capacity))
+    }
+
+    /// Creates a new `BytesMut` with default capacity.
+    ///
+    /// Resulting object has length 0 and unspecified capacity.
+    /// This function does not allocate.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    ///
+    /// let mut bytes = BytesMut::new();
+    ///
+    /// assert_eq!(0, bytes.len());
+    ///
+    /// bytes.reserve(2);
+    /// bytes.put_slice(b"xy");
+    ///
+    /// assert_eq!(&b"xy"[..], &bytes[..]);
+    /// ```
+    #[inline]
+    pub fn new() -> BytesMut {
+        BytesMut::with_capacity(0)
+    }
+
+    /// Returns the number of bytes contained in this `BytesMut`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let b = BytesMut::from(&b"hello"[..]);
+    /// assert_eq!(b.len(), 5);
+    /// ```
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns true if the `BytesMut` has a length of 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let b = BytesMut::with_capacity(64);
+    /// assert!(b.is_empty());
+    /// ```
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    /// Returns the number of bytes the `BytesMut` can hold without reallocating.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let b = BytesMut::with_capacity(64);
+    /// assert_eq!(b.capacity(), 64);
+    /// ```
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.cap
+    }
+
+    /// Converts `self` into an immutable `Bytes`.
+    ///
+    /// The conversion is zero cost and is used to indicate that the slice
+    /// referenced by the handle will no longer be mutated. Once the conversion
+    /// is done, the handle can be cloned and shared across threads.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    /// use std::thread;
+    ///
+    /// let mut b = BytesMut::with_capacity(64);
+    /// b.put(&b"hello world"[..]);
+    /// let b1 = b.freeze();
+    /// let b2 = b1.clone();
+    ///
+    /// let th = thread::spawn(move || {
+    ///     assert_eq!(&b1[..], b"hello world");
+    /// });
+    ///
+    /// assert_eq!(&b2[..], b"hello world");
+    /// th.join().unwrap();
+    /// ```
+    #[inline]
+    pub fn freeze(self) -> Bytes {
+        let bytes = ManuallyDrop::new(self);
+        if bytes.kind() == KIND_VEC {
+            // Just re-use `Bytes` internal Vec vtable
+            unsafe {
+                let off = bytes.get_vec_pos();
+                let vec = rebuild_vec(bytes.ptr.as_ptr(), bytes.len, bytes.cap, off);
+                let mut b: Bytes = vec.into();
+                b.advance(off);
+                b
+            }
+        } else {
+            debug_assert_eq!(bytes.kind(), KIND_ARC);
+
+            let ptr = bytes.ptr.as_ptr();
+            let len = bytes.len;
+            let data = AtomicPtr::new(bytes.data.cast());
+            unsafe { Bytes::with_vtable(ptr, len, data, &SHARED_VTABLE) }
+        }
+    }
+
+    /// Creates a new `BytesMut`, which is initialized with zero.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let zeros = BytesMut::zeroed(42);
+    ///
+    /// assert_eq!(zeros.len(), 42);
+    /// zeros.into_iter().for_each(|x| assert_eq!(x, 0));
+    /// ```
+    pub fn zeroed(len: usize) -> BytesMut {
+        BytesMut::from_vec(vec![0; len])
+    }
+
+    /// Splits the bytes into two at the given index.
+    ///
+    /// Afterwards `self` contains elements `[0, at)`, and the returned
+    /// `BytesMut` contains elements `[at, capacity)`.
+    ///
+    /// This is an `O(1)` operation that just increases the reference count
+    /// and sets a few indices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut a = BytesMut::from(&b"hello world"[..]);
+    /// let mut b = a.split_off(5);
+    ///
+    /// a[0] = b'j';
+    /// b[0] = b'!';
+    ///
+    /// assert_eq!(&a[..], b"jello");
+    /// assert_eq!(&b[..], b"!world");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > capacity`.
+    #[must_use = "consider BytesMut::truncate if you don't need the other half"]
+    pub fn split_off(&mut self, at: usize) -> BytesMut {
+        assert!(
+            at <= self.capacity(),
+            "split_off out of bounds: {:?} <= {:?}",
+            at,
+            self.capacity(),
+        );
+        unsafe {
+            let mut other = self.shallow_clone();
+            // SAFETY: We've checked that `at` <= `self.capacity()` above.
+            other.advance_unchecked(at);
+            self.cap = at;
+            self.len = cmp::min(self.len, at);
+            other
+        }
+    }
+
+    /// Removes the bytes from the current view, returning them in a new
+    /// `BytesMut` handle.
+    ///
+    /// Afterwards, `self` will be empty, but will retain any additional
+    /// capacity that it had before the operation. This is identical to
+    /// `self.split_to(self.len())`.
+    ///
+    /// This is an `O(1)` operation that just increases the reference count and
+    /// sets a few indices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    ///
+    /// let mut buf = BytesMut::with_capacity(1024);
+    /// buf.put(&b"hello world"[..]);
+    ///
+    /// let other = buf.split();
+    ///
+    /// assert!(buf.is_empty());
+    /// assert_eq!(1013, buf.capacity());
+    ///
+    /// assert_eq!(other, b"hello world"[..]);
+    /// ```
+    #[must_use = "consider BytesMut::advance(len()) if you don't need the other half"]
+    pub fn split(&mut self) -> BytesMut {
+        let len = self.len();
+        self.split_to(len)
+    }
+
+    /// Splits the buffer into two at the given index.
+    ///
+    /// Afterwards `self` contains elements `[at, len)`, and the returned `BytesMut`
+    /// contains elements `[0, at)`.
+    ///
+    /// This is an `O(1)` operation that just increases the reference count and
+    /// sets a few indices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut a = BytesMut::from(&b"hello world"[..]);
+    /// let mut b = a.split_to(5);
+    ///
+    /// a[0] = b'!';
+    /// b[0] = b'j';
+    ///
+    /// assert_eq!(&a[..], b"!world");
+    /// assert_eq!(&b[..], b"jello");
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > len`.
+    #[must_use = "consider BytesMut::advance if you don't need the other half"]
+    pub fn split_to(&mut self, at: usize) -> BytesMut {
+        assert!(
+            at <= self.len(),
+            "split_to out of bounds: {:?} <= {:?}",
+            at,
+            self.len(),
+        );
+
+        unsafe {
+            let mut other = self.shallow_clone();
+            // SAFETY: We've checked that `at` <= `self.len()` and we know that `self.len()` <=
+            // `self.capacity()`.
+            self.advance_unchecked(at);
+            other.cap = at;
+            other.len = at;
+            other
+        }
+    }
+
+    /// Shortens the buffer, keeping the first `len` bytes and dropping the
+    /// rest.
+    ///
+    /// If `len` is greater than the buffer's current length, this has no
+    /// effect.
+    ///
+    /// Existing underlying capacity is preserved.
+    ///
+    /// The [split_off](`Self::split_off()`) method can emulate `truncate`, but this causes the
+    /// excess bytes to be returned instead of dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::from(&b"hello world"[..]);
+    /// buf.truncate(5);
+    /// assert_eq!(buf, b"hello"[..]);
+    /// ```
+    pub fn truncate(&mut self, len: usize) {
+        if len < self.len() {
+            unsafe {
+                // SAFETY: Shrinking the buffer cannot expose uninitialized bytes.
+                self.set_len(len);
+            }
+        }
+    }
+
+    /// Clears the buffer, removing all data. Existing capacity is preserved.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::from(&b"hello world"[..]);
+    /// buf.clear();
+    /// assert!(buf.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        self.truncate(0);
+    }
+
+    /// Resizes the buffer so that `len` is equal to `new_len`.
+    ///
+    /// If `new_len` is greater than `len`, the buffer is extended by the
+    /// difference with each additional byte set to `value`. If `new_len` is
+    /// less than `len`, the buffer is simply truncated.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::new();
+    ///
+    /// buf.resize(3, 0x1);
+    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
+    ///
+    /// buf.resize(2, 0x2);
+    /// assert_eq!(&buf[..], &[0x1, 0x1]);
+    ///
+    /// buf.resize(4, 0x3);
+    /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
+    /// ```
+    pub fn resize(&mut self, new_len: usize, value: u8) {
+        let additional = if let Some(additional) = new_len.checked_sub(self.len()) {
+            additional
+        } else {
+            self.truncate(new_len);
+            return;
+        };
+
+        if additional == 0 {
+            return;
+        }
+
+        self.reserve(additional);
+        let dst = self.spare_capacity_mut().as_mut_ptr();
+        // SAFETY: `spare_capacity_mut` returns a valid, properly aligned pointer and we've
+        // reserved enough space to write `additional` bytes.
+        unsafe { ptr::write_bytes(dst, value, additional) };
+
+        // SAFETY: There are at least `new_len` initialized bytes in the buffer so no
+        // uninitialized bytes are being exposed.
+        unsafe { self.set_len(new_len) };
+    }
+
+    /// Sets the length of the buffer.
+    ///
+    /// This will explicitly set the size of the buffer without actually
+    /// modifying the data, so it is up to the caller to ensure that the data
+    /// has been initialized.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut b = BytesMut::from(&b"hello world"[..]);
+    ///
+    /// unsafe {
+    ///     b.set_len(5);
+    /// }
+    ///
+    /// assert_eq!(&b[..], b"hello");
+    ///
+    /// unsafe {
+    ///     b.set_len(11);
+    /// }
+    ///
+    /// assert_eq!(&b[..], b"hello world");
+    /// ```
+    #[inline]
+    pub unsafe fn set_len(&mut self, len: usize) {
+        debug_assert!(len <= self.cap, "set_len out of bounds");
+        self.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.
+    ///
+    /// Before allocating new buffer space, the function will attempt to reclaim
+    /// space in the existing buffer. If the current handle references a view
+    /// into a larger original buffer, and all other handles referencing part
+    /// of the same original buffer have been dropped, then the current view
+    /// can be copied/shifted to the front of the buffer and the handle can take
+    /// ownership of the full buffer, provided that the full buffer is large
+    /// enough to fit the requested additional capacity.
+    ///
+    /// This optimization will only happen if shifting the data from the current
+    /// view to the front of the buffer is not too expensive in terms of the
+    /// (amortized) time required. The precise condition is subject to change;
+    /// as of now, the length of the data being shifted needs to be at least as
+    /// large as the distance that it's shifted by. If the current view is empty
+    /// and the original buffer is large enough to fit the requested additional
+    /// capacity, then reallocations will never happen.
+    ///
+    /// # Examples
+    ///
+    /// In the following example, a new buffer is allocated.
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::from(&b"hello"[..]);
+    /// buf.reserve(64);
+    /// assert!(buf.capacity() >= 69);
+    /// ```
+    ///
+    /// In the following example, the existing buffer is reclaimed.
+    ///
+    /// ```
+    /// use bytes::{BytesMut, BufMut};
+    ///
+    /// let mut buf = BytesMut::with_capacity(128);
+    /// buf.put(&[0; 64][..]);
+    ///
+    /// let ptr = buf.as_ptr();
+    /// let other = buf.split();
+    ///
+    /// assert!(buf.is_empty());
+    /// assert_eq!(buf.capacity(), 64);
+    ///
+    /// drop(other);
+    /// buf.reserve(128);
+    ///
+    /// assert_eq!(buf.capacity(), 128);
+    /// assert_eq!(buf.as_ptr(), ptr);
+    /// ```
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new capacity overflows `usize`.
+    #[inline]
+    pub fn reserve(&mut self, additional: usize) {
+        let len = self.len();
+        let rem = self.capacity() - len;
+
+        if additional <= rem {
+            // The handle can already store at least `additional` more bytes, so
+            // there is no further work needed to be done.
+            return;
+        }
+
+        self.reserve_inner(additional);
+    }
+
+    // In separate function to allow the short-circuits in `reserve` to
+    // be inline-able. Significant helps performance.
+    fn reserve_inner(&mut self, additional: usize) {
+        let len = self.len();
+        let kind = self.kind();
+
+        if kind == KIND_VEC {
+            // If there's enough free space before the start of the buffer, then
+            // just copy the data backwards and reuse the already-allocated
+            // space.
+            //
+            // Otherwise, since backed by a vector, use `Vec::reserve`
+            //
+            // We need to make sure that this optimization does not kill the
+            // amortized runtimes of BytesMut's operations.
+            unsafe {
+                let off = self.get_vec_pos();
+
+                // Only reuse space if we can satisfy the requested additional space.
+                //
+                // Also check if the value of `off` suggests that enough bytes
+                // have been read to account for the overhead of shifting all
+                // the data (in an amortized analysis).
+                // Hence the condition `off >= self.len()`.
+                //
+                // This condition also already implies that the buffer is going
+                // to be (at least) half-empty in the end; so we do not break
+                // the (amortized) runtime with future resizes of the underlying
+                // `Vec`.
+                //
+                // [For more details check issue #524, and PR #525.]
+                if self.capacity() - self.len() + off >= additional && off >= self.len() {
+                    // There's enough space, and it's not too much overhead:
+                    // reuse the space!
+                    //
+                    // Just move the pointer back to the start after copying
+                    // data back.
+                    let base_ptr = self.ptr.as_ptr().sub(off);
+                    // Since `off >= self.len()`, the two regions don't overlap.
+                    ptr::copy_nonoverlapping(self.ptr.as_ptr(), base_ptr, self.len);
+                    self.ptr = vptr(base_ptr);
+                    self.set_vec_pos(0);
+
+                    // Length stays constant, but since we moved backwards we
+                    // can gain capacity back.
+                    self.cap += off;
+                } else {
+                    // Not enough space, or reusing might be too much overhead:
+                    // allocate more space!
+                    let mut v =
+                        ManuallyDrop::new(rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off));
+                    v.reserve(additional);
+
+                    // Update the info
+                    self.ptr = vptr(v.as_mut_ptr().add(off));
+                    self.cap = v.capacity() - off;
+                    debug_assert_eq!(self.len, v.len() - off);
+                }
+
+                return;
+            }
+        }
+
+        debug_assert_eq!(kind, KIND_ARC);
+        let shared: *mut Shared = self.data;
+
+        // Reserving involves abandoning the currently shared buffer and
+        // allocating a new vector with the requested capacity.
+        //
+        // Compute the new capacity
+        let mut new_cap = len.checked_add(additional).expect("overflow");
+
+        unsafe {
+            // First, try to reclaim the buffer. This is possible if the current
+            // handle is the only outstanding handle pointing to the buffer.
+            if (*shared).is_unique() {
+                // This is the only handle to the buffer. It can be reclaimed.
+                // However, before doing the work of copying data, check to make
+                // sure that the vector has enough capacity.
+                let v = &mut (*shared).vec;
+
+                let v_capacity = v.capacity();
+                let ptr = v.as_mut_ptr();
+
+                let offset = offset_from(self.ptr.as_ptr(), ptr);
+
+                // Compare the condition in the `kind == KIND_VEC` case above
+                // for more details.
+                if v_capacity >= new_cap + offset {
+                    self.cap = new_cap;
+                    // no copy is necessary
+                } else if v_capacity >= new_cap && offset >= len {
+                    // The capacity is sufficient, and copying is not too much
+                    // overhead: reclaim the buffer!
+
+                    // `offset >= len` means: no overlap
+                    ptr::copy_nonoverlapping(self.ptr.as_ptr(), ptr, len);
+
+                    self.ptr = vptr(ptr);
+                    self.cap = v.capacity();
+                } else {
+                    // calculate offset
+                    let off = (self.ptr.as_ptr() as usize) - (v.as_ptr() as usize);
+
+                    // new_cap is calculated in terms of `BytesMut`, not the underlying
+                    // `Vec`, so it does not take the offset into account.
+                    //
+                    // Thus we have to manually add it here.
+                    new_cap = new_cap.checked_add(off).expect("overflow");
+
+                    // The vector capacity is not sufficient. The reserve request is
+                    // asking for more than the initial buffer capacity. Allocate more
+                    // than requested if `new_cap` is not much bigger than the current
+                    // capacity.
+                    //
+                    // There are some situations, using `reserve_exact` that the
+                    // buffer capacity could be below `original_capacity`, so do a
+                    // check.
+                    let double = v.capacity().checked_shl(1).unwrap_or(new_cap);
+
+                    new_cap = cmp::max(double, new_cap);
+
+                    // No space - allocate more
+                    //
+                    // The length field of `Shared::vec` is not used by the `BytesMut`;
+                    // instead we use the `len` field in the `BytesMut` itself. However,
+                    // when calling `reserve`, it doesn't guarantee that data stored in
+                    // the unused capacity of the vector is copied over to the new
+                    // allocation, so we need to ensure that we don't have any data we
+                    // care about in the unused capacity before calling `reserve`.
+                    debug_assert!(off + len <= v.capacity());
+                    v.set_len(off + len);
+                    v.reserve(new_cap - v.len());
+
+                    // Update the info
+                    self.ptr = vptr(v.as_mut_ptr().add(off));
+                    self.cap = v.capacity() - off;
+                }
+
+                return;
+            }
+        }
+
+        let original_capacity_repr = unsafe { (*shared).original_capacity_repr };
+        let original_capacity = original_capacity_from_repr(original_capacity_repr);
+
+        new_cap = cmp::max(new_cap, original_capacity);
+
+        // Create a new vector to store the data
+        let mut v = ManuallyDrop::new(Vec::with_capacity(new_cap));
+
+        // Copy the bytes
+        v.extend_from_slice(self.as_ref());
+
+        // Release the shared handle. This must be done *after* the bytes are
+        // copied.
+        unsafe { release_shared(shared) };
+
+        // Update self
+        let data = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC;
+        self.data = invalid_ptr(data);
+        self.ptr = vptr(v.as_mut_ptr());
+        self.cap = v.capacity();
+        debug_assert_eq!(self.len, v.len());
+    }
+
+    /// Appends given bytes to this `BytesMut`.
+    ///
+    /// If this `BytesMut` object does not have enough capacity, it is resized
+    /// first.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::with_capacity(0);
+    /// buf.extend_from_slice(b"aaabbb");
+    /// buf.extend_from_slice(b"cccddd");
+    ///
+    /// assert_eq!(b"aaabbbcccddd", &buf[..]);
+    /// ```
+    #[inline]
+    pub fn extend_from_slice(&mut self, extend: &[u8]) {
+        let cnt = extend.len();
+        self.reserve(cnt);
+
+        unsafe {
+            let dst = self.spare_capacity_mut();
+            // Reserved above
+            debug_assert!(dst.len() >= cnt);
+
+            ptr::copy_nonoverlapping(extend.as_ptr(), dst.as_mut_ptr().cast(), cnt);
+        }
+
+        unsafe {
+            self.advance_mut(cnt);
+        }
+    }
+
+    /// Absorbs a `BytesMut` that was previously split off.
+    ///
+    /// If the two `BytesMut` objects were previously contiguous and not mutated
+    /// in a way that causes re-allocation i.e., if `other` was created by
+    /// calling `split_off` on this `BytesMut`, then this is an `O(1)` operation
+    /// that just decreases a reference count and sets a few indices.
+    /// Otherwise this method degenerates to
+    /// `self.extend_from_slice(other.as_ref())`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// let mut buf = BytesMut::with_capacity(64);
+    /// buf.extend_from_slice(b"aaabbbcccddd");
+    ///
+    /// let split = buf.split_off(6);
+    /// assert_eq!(b"aaabbb", &buf[..]);
+    /// assert_eq!(b"cccddd", &split[..]);
+    ///
+    /// buf.unsplit(split);
+    /// assert_eq!(b"aaabbbcccddd", &buf[..]);
+    /// ```
+    pub fn unsplit(&mut self, other: BytesMut) {
+        if self.is_empty() {
+            *self = other;
+            return;
+        }
+
+        if let Err(other) = self.try_unsplit(other) {
+            self.extend_from_slice(other.as_ref());
+        }
+    }
+
+    // private
+
+    // For now, use a `Vec` to manage the memory for us, but we may want to
+    // change that in the future to some alternate allocator strategy.
+    //
+    // Thus, we don't expose an easy way to construct from a `Vec` since an
+    // internal change could make a simple pattern (`BytesMut::from(vec)`)
+    // suddenly a lot more expensive.
+    #[inline]
+    pub(crate) fn from_vec(vec: Vec<u8>) -> BytesMut {
+        let mut vec = ManuallyDrop::new(vec);
+        let ptr = vptr(vec.as_mut_ptr());
+        let len = vec.len();
+        let cap = vec.capacity();
+
+        let original_capacity_repr = original_capacity_to_repr(cap);
+        let data = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC;
+
+        BytesMut {
+            ptr,
+            len,
+            cap,
+            data: invalid_ptr(data),
+        }
+    }
+
+    #[inline]
+    fn as_slice(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
+    }
+
+    #[inline]
+    fn as_slice_mut(&mut self) -> &mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
+    }
+
+    /// Advance the buffer without bounds checking.
+    ///
+    /// # SAFETY
+    ///
+    /// The caller must ensure that `count` <= `self.cap`.
+    unsafe fn advance_unchecked(&mut self, count: usize) {
+        // Setting the start to 0 is a no-op, so return early if this is the
+        // case.
+        if count == 0 {
+            return;
+        }
+
+        debug_assert!(count <= self.cap, "internal: set_start out of bounds");
+
+        let kind = self.kind();
+
+        if kind == KIND_VEC {
+            // Setting the start when in vec representation is a little more
+            // complicated. First, we have to track how far ahead the
+            // "start" of the byte buffer from the beginning of the vec. We
+            // also have to ensure that we don't exceed the maximum shift.
+            let pos = self.get_vec_pos() + count;
+
+            if pos <= MAX_VEC_POS {
+                self.set_vec_pos(pos);
+            } else {
+                // The repr must be upgraded to ARC. This will never happen
+                // on 64 bit systems and will only happen on 32 bit systems
+                // when shifting past 134,217,727 bytes. As such, we don't
+                // worry too much about performance here.
+                self.promote_to_shared(/*ref_count = */ 1);
+            }
+        }
+
+        // Updating the start of the view is setting `ptr` to point to the
+        // new start and updating the `len` field to reflect the new length
+        // of the view.
+        self.ptr = vptr(self.ptr.as_ptr().add(count));
+        self.len = self.len.checked_sub(count).unwrap_or(0);
+        self.cap -= count;
+    }
+
+    fn try_unsplit(&mut self, other: BytesMut) -> Result<(), BytesMut> {
+        if other.capacity() == 0 {
+            return Ok(());
+        }
+
+        let ptr = unsafe { self.ptr.as_ptr().add(self.len) };
+        if ptr == other.ptr.as_ptr()
+            && self.kind() == KIND_ARC
+            && other.kind() == KIND_ARC
+            && self.data == other.data
+        {
+            // Contiguous blocks, just combine directly
+            self.len += other.len;
+            self.cap += other.cap;
+            Ok(())
+        } else {
+            Err(other)
+        }
+    }
+
+    #[inline]
+    fn kind(&self) -> usize {
+        self.data as usize & KIND_MASK
+    }
+
+    unsafe fn promote_to_shared(&mut self, ref_cnt: usize) {
+        debug_assert_eq!(self.kind(), KIND_VEC);
+        debug_assert!(ref_cnt == 1 || ref_cnt == 2);
+
+        let original_capacity_repr =
+            (self.data as usize & ORIGINAL_CAPACITY_MASK) >> ORIGINAL_CAPACITY_OFFSET;
+
+        // The vec offset cannot be concurrently mutated, so there
+        // should be no danger reading it.
+        let off = (self.data as usize) >> VEC_POS_OFFSET;
+
+        // First, allocate a new `Shared` instance containing the
+        // `Vec` fields. It's important to note that `ptr`, `len`,
+        // and `cap` cannot be mutated without having `&mut self`.
+        // This means that these fields will not be concurrently
+        // updated and since the buffer hasn't been promoted to an
+        // `Arc`, those three fields still are the components of the
+        // vector.
+        let shared = Box::new(Shared {
+            vec: rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off),
+            original_capacity_repr,
+            ref_count: AtomicUsize::new(ref_cnt),
+        });
+
+        let shared = Box::into_raw(shared);
+
+        // The pointer should be aligned, so this assert should
+        // always succeed.
+        debug_assert_eq!(shared as usize & KIND_MASK, KIND_ARC);
+
+        self.data = shared;
+    }
+
+    /// Makes an exact shallow clone of `self`.
+    ///
+    /// The kind of `self` doesn't matter, but this is unsafe
+    /// because the clone will have the same offsets. You must
+    /// be sure the returned value to the user doesn't allow
+    /// two views into the same range.
+    #[inline]
+    unsafe fn shallow_clone(&mut self) -> BytesMut {
+        if self.kind() == KIND_ARC {
+            increment_shared(self.data);
+            ptr::read(self)
+        } else {
+            self.promote_to_shared(/*ref_count = */ 2);
+            ptr::read(self)
+        }
+    }
+
+    #[inline]
+    unsafe fn get_vec_pos(&self) -> usize {
+        debug_assert_eq!(self.kind(), KIND_VEC);
+
+        self.data as usize >> VEC_POS_OFFSET
+    }
+
+    #[inline]
+    unsafe fn set_vec_pos(&mut self, pos: usize) {
+        debug_assert_eq!(self.kind(), KIND_VEC);
+        debug_assert!(pos <= MAX_VEC_POS);
+
+        self.data = invalid_ptr((pos << VEC_POS_OFFSET) | (self.data as usize & NOT_VEC_POS_MASK));
+    }
+
+    /// Returns the remaining spare capacity of the buffer as a slice of `MaybeUninit<u8>`.
+    ///
+    /// The returned slice can be used to fill the buffer with data (e.g. by
+    /// reading from a file) before marking the data as initialized using the
+    /// [`set_len`] method.
+    ///
+    /// [`set_len`]: BytesMut::set_len
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bytes::BytesMut;
+    ///
+    /// // Allocate buffer big enough for 10 bytes.
+    /// let mut buf = BytesMut::with_capacity(10);
+    ///
+    /// // Fill in the first 3 elements.
+    /// let uninit = buf.spare_capacity_mut();
+    /// uninit[0].write(0);
+    /// uninit[1].write(1);
+    /// uninit[2].write(2);
+    ///
+    /// // Mark the first 3 bytes of the buffer as being initialized.
+    /// unsafe {
+    ///     buf.set_len(3);
+    /// }
+    ///
+    /// assert_eq!(&buf[..], &[0, 1, 2]);
+    /// ```
+    #[inline]
+    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+        unsafe {
+            let ptr = self.ptr.as_ptr().add(self.len);
+            let len = self.cap - self.len;
+
+            slice::from_raw_parts_mut(ptr.cast(), len)
+        }
+    }
+}
+
+impl Drop for BytesMut {
+    fn drop(&mut self) {
+        let kind = self.kind();
+
+        if kind == KIND_VEC {
+            unsafe {
+                let off = self.get_vec_pos();
+
+                // Vector storage, free the vector
+                let _ = rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off);
+            }
+        } else if kind == KIND_ARC {
+            unsafe { release_shared(self.data) };
+        }
+    }
+}
+
+impl Buf for BytesMut {
+    #[inline]
+    fn remaining(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn chunk(&self) -> &[u8] {
+        self.as_slice()
+    }
+
+    #[inline]
+    fn advance(&mut self, cnt: usize) {
+        assert!(
+            cnt <= self.remaining(),
+            "cannot advance past `remaining`: {:?} <= {:?}",
+            cnt,
+            self.remaining(),
+        );
+        unsafe {
+            // SAFETY: We've checked that `cnt` <= `self.remaining()` and we know that
+            // `self.remaining()` <= `self.cap`.
+            self.advance_unchecked(cnt);
+        }
+    }
+
+    fn copy_to_bytes(&mut self, len: usize) -> Bytes {
+        self.split_to(len).freeze()
+    }
+}
+
+unsafe impl BufMut for BytesMut {
+    #[inline]
+    fn remaining_mut(&self) -> usize {
+        usize::MAX - self.len()
+    }
+
+    #[inline]
+    unsafe fn advance_mut(&mut self, cnt: usize) {
+        let remaining = self.cap - self.len();
+        if cnt > remaining {
+            super::panic_advance(cnt, remaining);
+        }
+        // Addition won't overflow since it is at most `self.cap`.
+        self.len = self.len() + cnt;
+    }
+
+    #[inline]
+    fn chunk_mut(&mut self) -> &mut UninitSlice {
+        if self.capacity() == self.len() {
+            self.reserve(64);
+        }
+        self.spare_capacity_mut().into()
+    }
+
+    // Specialize these methods so they can skip checking `remaining_mut`
+    // and `advance_mut`.
+
+    fn put<T: Buf>(&mut self, mut src: T)
+    where
+        Self: Sized,
+    {
+        while src.has_remaining() {
+            let s = src.chunk();
+            let l = s.len();
+            self.extend_from_slice(s);
+            src.advance(l);
+        }
+    }
+
+    fn put_slice(&mut self, src: &[u8]) {
+        self.extend_from_slice(src);
+    }
+
+    fn put_bytes(&mut self, val: u8, cnt: usize) {
+        self.reserve(cnt);
+        unsafe {
+            let dst = self.spare_capacity_mut();
+            // Reserved above
+            debug_assert!(dst.len() >= cnt);
+
+            ptr::write_bytes(dst.as_mut_ptr(), val, cnt);
+
+            self.advance_mut(cnt);
+        }
+    }
+}
+
+impl AsRef<[u8]> for BytesMut {
+    #[inline]
+    fn as_ref(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl Deref for BytesMut {
+    type Target = [u8];
+
+    #[inline]
+    fn deref(&self) -> &[u8] {
+        self.as_ref()
+    }
+}
+
+impl AsMut<[u8]> for BytesMut {
+    #[inline]
+    fn as_mut(&mut self) -> &mut [u8] {
+        self.as_slice_mut()
+    }
+}
+
+impl DerefMut for BytesMut {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut [u8] {
+        self.as_mut()
+    }
+}
+
+impl<'a> From<&'a [u8]> for BytesMut {
+    fn from(src: &'a [u8]) -> BytesMut {
+        BytesMut::from_vec(src.to_vec())
+    }
+}
+
+impl<'a> From<&'a str> for BytesMut {
+    fn from(src: &'a str) -> BytesMut {
+        BytesMut::from(src.as_bytes())
+    }
+}
+
+impl From<BytesMut> for Bytes {
+    fn from(src: BytesMut) -> Bytes {
+        src.freeze()
+    }
+}
+
+impl PartialEq for BytesMut {
+    fn eq(&self, other: &BytesMut) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl PartialOrd for BytesMut {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        self.as_slice().partial_cmp(other.as_slice())
+    }
+}
+
+impl Ord for BytesMut {
+    fn cmp(&self, other: &BytesMut) -> cmp::Ordering {
+        self.as_slice().cmp(other.as_slice())
+    }
+}
+
+impl Eq for BytesMut {}
+
+impl Default for BytesMut {
+    #[inline]
+    fn default() -> BytesMut {
+        BytesMut::new()
+    }
+}
+
+impl hash::Hash for BytesMut {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: hash::Hasher,
+    {
+        let s: &[u8] = self.as_ref();
+        s.hash(state);
+    }
+}
+
+impl Borrow<[u8]> for BytesMut {
+    fn borrow(&self) -> &[u8] {
+        self.as_ref()
+    }
+}
+
+impl BorrowMut<[u8]> for BytesMut {
+    fn borrow_mut(&mut self) -> &mut [u8] {
+        self.as_mut()
+    }
+}
+
+impl fmt::Write for BytesMut {
+    #[inline]
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        if self.remaining_mut() >= s.len() {
+            self.put_slice(s.as_bytes());
+            Ok(())
+        } else {
+            Err(fmt::Error)
+        }
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
+        fmt::write(self, args)
+    }
+}
+
+impl Clone for BytesMut {
+    fn clone(&self) -> BytesMut {
+        BytesMut::from(&self[..])
+    }
+}
+
+impl IntoIterator for BytesMut {
+    type Item = u8;
+    type IntoIter = IntoIter<BytesMut>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter::new(self)
+    }
+}
+
+impl<'a> IntoIterator for &'a BytesMut {
+    type Item = &'a u8;
+    type IntoIter = core::slice::Iter<'a, u8>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.as_ref().iter()
+    }
+}
+
+impl Extend<u8> for BytesMut {
+    fn extend<T>(&mut self, iter: T)
+    where
+        T: IntoIterator<Item = u8>,
+    {
+        let iter = iter.into_iter();
+
+        let (lower, _) = iter.size_hint();
+        self.reserve(lower);
+
+        // TODO: optimize
+        // 1. If self.kind() == KIND_VEC, use Vec::extend
+        for b in iter {
+            self.put_u8(b);
+        }
+    }
+}
+
+impl<'a> Extend<&'a u8> for BytesMut {
+    fn extend<T>(&mut self, iter: T)
+    where
+        T: IntoIterator<Item = &'a u8>,
+    {
+        self.extend(iter.into_iter().copied())
+    }
+}
+
+impl Extend<Bytes> for BytesMut {
+    fn extend<T>(&mut self, iter: T)
+    where
+        T: IntoIterator<Item = Bytes>,
+    {
+        for bytes in iter {
+            self.extend_from_slice(&bytes)
+        }
+    }
+}
+
+impl FromIterator<u8> for BytesMut {
+    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
+        BytesMut::from_vec(Vec::from_iter(into_iter))
+    }
+}
+
+impl<'a> FromIterator<&'a u8> for BytesMut {
+    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
+        BytesMut::from_iter(into_iter.into_iter().copied())
+    }
+}
+
+/*
+ *
+ * ===== Inner =====
+ *
+ */
+
+unsafe fn increment_shared(ptr: *mut Shared) {
+    let old_size = (*ptr).ref_count.fetch_add(1, Ordering::Relaxed);
+
+    if old_size > isize::MAX as usize {
+        crate::abort();
+    }
+}
+
+unsafe fn release_shared(ptr: *mut Shared) {
+    // `Shared` storage... follow the drop steps from Arc.
+    if (*ptr).ref_count.fetch_sub(1, Ordering::Release) != 1 {
+        return;
+    }
+
+    // This fence is needed to prevent reordering of use of the data and
+    // deletion of the data.  Because it is marked `Release`, the decreasing
+    // of the reference count synchronizes with this `Acquire` fence. This
+    // means that use of the data happens before decreasing the reference
+    // count, which happens before this fence, which happens before the
+    // deletion of the data.
+    //
+    // As explained in the [Boost documentation][1],
+    //
+    // > It is important to enforce any possible access to the object in one
+    // > thread (through an existing reference) to *happen before* deleting
+    // > the object in a different thread. This is achieved by a "release"
+    // > operation after dropping a reference (any access to the object
+    // > through this reference must obviously happened before), and an
+    // > "acquire" operation before deleting the object.
+    //
+    // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
+    //
+    // Thread sanitizer does not support atomic fences. Use an atomic load
+    // instead.
+    (*ptr).ref_count.load(Ordering::Acquire);
+
+    // Drop the data
+    drop(Box::from_raw(ptr));
+}
+
+impl Shared {
+    fn is_unique(&self) -> bool {
+        // The goal is to check if the current handle is the only handle
+        // that currently has access to the buffer. This is done by
+        // checking if the `ref_count` is currently 1.
+        //
+        // The `Acquire` ordering synchronizes with the `Release` as
+        // part of the `fetch_sub` in `release_shared`. The `fetch_sub`
+        // operation guarantees that any mutations done in other threads
+        // are ordered before the `ref_count` is decremented. As such,
+        // this `Acquire` will guarantee that those mutations are
+        // visible to the current thread.
+        self.ref_count.load(Ordering::Acquire) == 1
+    }
+}
+
+#[inline]
+fn original_capacity_to_repr(cap: usize) -> usize {
+    let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize);
+    cmp::min(
+        width,
+        MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH,
+    )
+}
+
+fn original_capacity_from_repr(repr: usize) -> usize {
+    if repr == 0 {
+        return 0;
+    }
+
+    1 << (repr + (MIN_ORIGINAL_CAPACITY_WIDTH - 1))
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_original_capacity_to_repr() {
+        assert_eq!(original_capacity_to_repr(0), 0);
+
+        let max_width = 32;
+
+        for width in 1..(max_width + 1) {
+            let cap = 1 << width - 1;
+
+            let expected = if width < MIN_ORIGINAL_CAPACITY_WIDTH {
+                0
+            } else if width < MAX_ORIGINAL_CAPACITY_WIDTH {
+                width - MIN_ORIGINAL_CAPACITY_WIDTH
+            } else {
+                MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH
+            };
+
+            assert_eq!(original_capacity_to_repr(cap), expected);
+
+            if width > 1 {
+                assert_eq!(original_capacity_to_repr(cap + 1), expected);
+            }
+
+            //  MIN_ORIGINAL_CAPACITY_WIDTH must be bigger than 7 to pass tests below
+            if width == MIN_ORIGINAL_CAPACITY_WIDTH + 1 {
+                assert_eq!(original_capacity_to_repr(cap - 24), expected - 1);
+                assert_eq!(original_capacity_to_repr(cap + 76), expected);
+            } else if width == MIN_ORIGINAL_CAPACITY_WIDTH + 2 {
+                assert_eq!(original_capacity_to_repr(cap - 1), expected - 1);
+                assert_eq!(original_capacity_to_repr(cap - 48), expected - 1);
+            }
+        }
+    }
+
+    #[test]
+    fn test_original_capacity_from_repr() {
+        assert_eq!(0, original_capacity_from_repr(0));
+
+        let min_cap = 1 << MIN_ORIGINAL_CAPACITY_WIDTH;
+
+        assert_eq!(min_cap, original_capacity_from_repr(1));
+        assert_eq!(min_cap * 2, original_capacity_from_repr(2));
+        assert_eq!(min_cap * 4, original_capacity_from_repr(3));
+        assert_eq!(min_cap * 8, original_capacity_from_repr(4));
+        assert_eq!(min_cap * 16, original_capacity_from_repr(5));
+        assert_eq!(min_cap * 32, original_capacity_from_repr(6));
+        assert_eq!(min_cap * 64, original_capacity_from_repr(7));
+    }
+}
+
+unsafe impl Send for BytesMut {}
+unsafe impl Sync for BytesMut {}
+
+/*
+ *
+ * ===== PartialEq / PartialOrd =====
+ *
+ */
+
+impl PartialEq<[u8]> for BytesMut {
+    fn eq(&self, other: &[u8]) -> bool {
+        &**self == other
+    }
+}
+
+impl PartialOrd<[u8]> for BytesMut {
+    fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
+        (**self).partial_cmp(other)
+    }
+}
+
+impl PartialEq<BytesMut> for [u8] {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for [u8] {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
+    }
+}
+
+impl PartialEq<str> for BytesMut {
+    fn eq(&self, other: &str) -> bool {
+        &**self == other.as_bytes()
+    }
+}
+
+impl PartialOrd<str> for BytesMut {
+    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
+        (**self).partial_cmp(other.as_bytes())
+    }
+}
+
+impl PartialEq<BytesMut> for str {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for str {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
+    }
+}
+
+impl PartialEq<Vec<u8>> for BytesMut {
+    fn eq(&self, other: &Vec<u8>) -> bool {
+        *self == other[..]
+    }
+}
+
+impl PartialOrd<Vec<u8>> for BytesMut {
+    fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
+        (**self).partial_cmp(&other[..])
+    }
+}
+
+impl PartialEq<BytesMut> for Vec<u8> {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for Vec<u8> {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        other.partial_cmp(self)
+    }
+}
+
+impl PartialEq<String> for BytesMut {
+    fn eq(&self, other: &String) -> bool {
+        *self == other[..]
+    }
+}
+
+impl PartialOrd<String> for BytesMut {
+    fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
+        (**self).partial_cmp(other.as_bytes())
+    }
+}
+
+impl PartialEq<BytesMut> for String {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for String {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self.as_bytes(), other)
+    }
+}
+
+impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut
+where
+    BytesMut: PartialEq<T>,
+{
+    fn eq(&self, other: &&'a T) -> bool {
+        *self == **other
+    }
+}
+
+impl<'a, T: ?Sized> PartialOrd<&'a T> for BytesMut
+where
+    BytesMut: PartialOrd<T>,
+{
+    fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
+        self.partial_cmp(*other)
+    }
+}
+
+impl PartialEq<BytesMut> for &[u8] {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for &[u8] {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        <[u8] as PartialOrd<[u8]>>::partial_cmp(self, other)
+    }
+}
+
+impl PartialEq<BytesMut> for &str {
+    fn eq(&self, other: &BytesMut) -> bool {
+        *other == *self
+    }
+}
+
+impl PartialOrd<BytesMut> for &str {
+    fn partial_cmp(&self, other: &BytesMut) -> Option<cmp::Ordering> {
+        other.partial_cmp(self)
+    }
+}
+
+impl PartialEq<BytesMut> for Bytes {
+    fn eq(&self, other: &BytesMut) -> bool {
+        other[..] == self[..]
+    }
+}
+
+impl PartialEq<Bytes> for BytesMut {
+    fn eq(&self, other: &Bytes) -> bool {
+        other[..] == self[..]
+    }
+}
+
+impl From<BytesMut> for Vec<u8> {
+    fn from(bytes: BytesMut) -> Self {
+        let kind = bytes.kind();
+        let bytes = ManuallyDrop::new(bytes);
+
+        let mut vec = if kind == KIND_VEC {
+            unsafe {
+                let off = bytes.get_vec_pos();
+                rebuild_vec(bytes.ptr.as_ptr(), bytes.len, bytes.cap, off)
+            }
+        } else {
+            let shared = bytes.data as *mut Shared;
+
+            if unsafe { (*shared).is_unique() } {
+                let vec = mem::replace(unsafe { &mut (*shared).vec }, Vec::new());
+
+                unsafe { release_shared(shared) };
+
+                vec
+            } else {
+                return ManuallyDrop::into_inner(bytes).deref().to_vec();
+            }
+        };
+
+        let len = bytes.len;
+
+        unsafe {
+            ptr::copy(bytes.ptr.as_ptr(), vec.as_mut_ptr(), len);
+            vec.set_len(len);
+        }
+
+        vec
+    }
+}
+
+#[inline]
+fn vptr(ptr: *mut u8) -> NonNull<u8> {
+    if cfg!(debug_assertions) {
+        NonNull::new(ptr).expect("Vec pointer should be non-null")
+    } else {
+        unsafe { NonNull::new_unchecked(ptr) }
+    }
+}
+
+/// Returns a dangling pointer with the given address. This is used to store
+/// integer data in pointer fields.
+///
+/// It is equivalent to `addr as *mut T`, but this fails on miri when strict
+/// provenance checking is enabled.
+#[inline]
+fn invalid_ptr<T>(addr: usize) -> *mut T {
+    let ptr = core::ptr::null_mut::<u8>().wrapping_add(addr);
+    debug_assert_eq!(ptr as usize, addr);
+    ptr.cast::<T>()
+}
+
+/// Precondition: dst >= original
+///
+/// The following line is equivalent to:
+///
+/// ```rust,ignore
+/// self.ptr.as_ptr().offset_from(ptr) as usize;
+/// ```
+///
+/// But due to min rust is 1.39 and it is only stabilized
+/// in 1.47, we cannot use it.
+#[inline]
+fn offset_from(dst: *mut u8, original: *mut u8) -> usize {
+    debug_assert!(dst >= original);
+
+    dst as usize - original as usize
+}
+
+unsafe fn rebuild_vec(ptr: *mut u8, mut len: usize, mut cap: usize, off: usize) -> Vec<u8> {
+    let ptr = ptr.sub(off);
+    len += off;
+    cap += off;
+
+    Vec::from_raw_parts(ptr, len, cap)
+}
+
+// ===== impl SharedVtable =====
+
+static SHARED_VTABLE: Vtable = Vtable {
+    clone: shared_v_clone,
+    to_vec: shared_v_to_vec,
+    is_unique: crate::bytes::shared_is_unique,
+    drop: shared_v_drop,
+};
+
+unsafe fn shared_v_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
+    let shared = data.load(Ordering::Relaxed) as *mut Shared;
+    increment_shared(shared);
+
+    let data = AtomicPtr::new(shared as *mut ());
+    Bytes::with_vtable(ptr, len, data, &SHARED_VTABLE)
+}
+
+unsafe fn shared_v_to_vec(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Vec<u8> {
+    let shared: *mut Shared = data.load(Ordering::Relaxed).cast();
+
+    if (*shared).is_unique() {
+        let shared = &mut *shared;
+
+        // Drop shared
+        let mut vec = mem::replace(&mut shared.vec, Vec::new());
+        release_shared(shared);
+
+        // Copy back buffer
+        ptr::copy(ptr, vec.as_mut_ptr(), len);
+        vec.set_len(len);
+
+        vec
+    } else {
+        let v = slice::from_raw_parts(ptr, len).to_vec();
+        release_shared(shared);
+        v
+    }
+}
+
+unsafe fn shared_v_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
+    data.with_mut(|shared| {
+        release_shared(*shared as *mut Shared);
+    });
+}
+
+// compile-fails
+
+/// ```compile_fail
+/// use bytes::BytesMut;
+/// #[deny(unused_must_use)]
+/// {
+///     let mut b1 = BytesMut::from("hello world");
+///     b1.split_to(6);
+/// }
+/// ```
+fn _split_to_must_use() {}
+
+/// ```compile_fail
+/// use bytes::BytesMut;
+/// #[deny(unused_must_use)]
+/// {
+///     let mut b1 = BytesMut::from("hello world");
+///     b1.split_off(6);
+/// }
+/// ```
+fn _split_off_must_use() {}
+
+/// ```compile_fail
+/// use bytes::BytesMut;
+/// #[deny(unused_must_use)]
+/// {
+///     let mut b1 = BytesMut::from("hello world");
+///     b1.split();
+/// }
+/// ```
+fn _split_must_use() {}
+
+// fuzz tests
+#[cfg(all(test, loom))]
+mod fuzz {
+    use loom::sync::Arc;
+    use loom::thread;
+
+    use super::BytesMut;
+    use crate::Bytes;
+
+    #[test]
+    fn bytes_mut_cloning_frozen() {
+        loom::model(|| {
+            let a = BytesMut::from(&b"abcdefgh"[..]).split().freeze();
+            let addr = a.as_ptr() as usize;
+
+            // test the Bytes::clone is Sync by putting it in an Arc
+            let a1 = Arc::new(a);
+            let a2 = a1.clone();
+
+            let t1 = thread::spawn(move || {
+                let b: Bytes = (*a1).clone();
+                assert_eq!(b.as_ptr() as usize, addr);
+            });
+
+            let t2 = thread::spawn(move || {
+                let b: Bytes = (*a2).clone();
+                assert_eq!(b.as_ptr() as usize, addr);
+            });
+
+            t1.join().unwrap();
+            t2.join().unwrap();
+        });
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/fmt/debug.rs.html b/src/bytes/fmt/debug.rs.html new file mode 100644 index 000000000..f3aa0dfad --- /dev/null +++ b/src/bytes/fmt/debug.rs.html @@ -0,0 +1,100 @@ +debug.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+
use core::fmt::{Debug, Formatter, Result};
+
+use super::BytesRef;
+use crate::{Bytes, BytesMut};
+
+/// Alternative implementation of `std::fmt::Debug` for byte slice.
+///
+/// Standard `Debug` implementation for `[u8]` is comma separated
+/// list of numbers. Since large amount of byte strings are in fact
+/// ASCII strings or contain a lot of ASCII strings (e. g. HTTP),
+/// it is convenient to print strings as ASCII when possible.
+impl Debug for BytesRef<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        write!(f, "b\"")?;
+        for &b in self.0 {
+            // https://doc.rust-lang.org/reference/tokens.html#byte-escapes
+            if b == b'\n' {
+                write!(f, "\\n")?;
+            } else if b == b'\r' {
+                write!(f, "\\r")?;
+            } else if b == b'\t' {
+                write!(f, "\\t")?;
+            } else if b == b'\\' || b == b'"' {
+                write!(f, "\\{}", b as char)?;
+            } else if b == b'\0' {
+                write!(f, "\\0")?;
+            // ASCII printable
+            } else if (0x20..0x7f).contains(&b) {
+                write!(f, "{}", b as char)?;
+            } else {
+                write!(f, "\\x{:02x}", b)?;
+            }
+        }
+        write!(f, "\"")?;
+        Ok(())
+    }
+}
+
+impl Debug for Bytes {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        Debug::fmt(&BytesRef(self.as_ref()), f)
+    }
+}
+
+impl Debug for BytesMut {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        Debug::fmt(&BytesRef(self.as_ref()), f)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/fmt/hex.rs.html b/src/bytes/fmt/hex.rs.html new file mode 100644 index 000000000..3554e0e3b --- /dev/null +++ b/src/bytes/fmt/hex.rs.html @@ -0,0 +1,76 @@ +hex.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+
use core::fmt::{Formatter, LowerHex, Result, UpperHex};
+
+use super::BytesRef;
+use crate::{Bytes, BytesMut};
+
+impl LowerHex for BytesRef<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        for &b in self.0 {
+            write!(f, "{:02x}", b)?;
+        }
+        Ok(())
+    }
+}
+
+impl UpperHex for BytesRef<'_> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        for &b in self.0 {
+            write!(f, "{:02X}", b)?;
+        }
+        Ok(())
+    }
+}
+
+macro_rules! hex_impl {
+    ($tr:ident, $ty:ty) => {
+        impl $tr for $ty {
+            fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+                $tr::fmt(&BytesRef(self.as_ref()), f)
+            }
+        }
+    };
+}
+
+hex_impl!(LowerHex, Bytes);
+hex_impl!(LowerHex, BytesMut);
+hex_impl!(UpperHex, Bytes);
+hex_impl!(UpperHex, BytesMut);
+
+
\ No newline at end of file diff --git a/src/bytes/fmt/mod.rs.html b/src/bytes/fmt/mod.rs.html new file mode 100644 index 000000000..aafa5c701 --- /dev/null +++ b/src/bytes/fmt/mod.rs.html @@ -0,0 +1,12 @@ +mod.rs - source
1
+2
+3
+4
+5
+
mod debug;
+mod hex;
+
+/// `BytesRef` is not a part of public API of bytes crate.
+struct BytesRef<'a>(&'a [u8]);
+
+
\ No newline at end of file diff --git a/src/bytes/lib.rs.html b/src/bytes/lib.rs.html new file mode 100644 index 000000000..654225113 --- /dev/null +++ b/src/bytes/lib.rs.html @@ -0,0 +1,300 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
+#![doc(test(
+    no_crate_inject,
+    attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
+))]
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+
+//! Provides abstractions for working with bytes.
+//!
+//! The `bytes` crate provides an efficient byte buffer structure
+//! ([`Bytes`]) and traits for working with buffer
+//! implementations ([`Buf`], [`BufMut`]).
+//!
+//! # `Bytes`
+//!
+//! `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. This is managed by
+//! using a reference count to track when the memory is no longer needed and can
+//! be freed.
+//!
+//! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]`
+//! or `Vec<u8>`), but usually a `BytesMut` is used first and written to. For
+//! example:
+//!
+//! ```rust
+//! use bytes::{BytesMut, BufMut};
+//!
+//! let mut buf = BytesMut::with_capacity(1024);
+//! buf.put(&b"hello world"[..]);
+//! buf.put_u16(1234);
+//!
+//! let a = buf.split();
+//! assert_eq!(a, b"hello world\x04\xD2"[..]);
+//!
+//! buf.put(&b"goodbye world"[..]);
+//!
+//! let b = buf.split();
+//! assert_eq!(b, b"goodbye world"[..]);
+//!
+//! assert_eq!(buf.capacity(), 998);
+//! ```
+//!
+//! In the above example, only a single buffer of 1024 is allocated. The handles
+//! `a` and `b` will share the underlying buffer and maintain indices tracking
+//! the view into the buffer represented by the handle.
+//!
+//! See the [struct docs](`Bytes`) 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] 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.
+//!
+//! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure)
+//!
+//! ## Relation with `Read` and `Write`
+//!
+//! At first glance, it may seem that `Buf` and `BufMut` overlap in
+//! functionality with [`std::io::Read`] 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.
+
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+pub mod buf;
+pub use crate::buf::{Buf, BufMut};
+
+mod bytes;
+mod bytes_mut;
+mod fmt;
+mod loom;
+pub use crate::bytes::Bytes;
+pub use crate::bytes_mut::BytesMut;
+
+// Optional Serde support
+#[cfg(feature = "serde")]
+mod serde;
+
+#[inline(never)]
+#[cold]
+fn abort() -> ! {
+    #[cfg(feature = "std")]
+    {
+        std::process::abort();
+    }
+
+    #[cfg(not(feature = "std"))]
+    {
+        struct Abort;
+        impl Drop for Abort {
+            fn drop(&mut self) {
+                panic!();
+            }
+        }
+        let _a = Abort;
+        panic!("abort");
+    }
+}
+
+#[inline(always)]
+#[cfg(feature = "std")]
+fn saturating_sub_usize_u64(a: usize, b: u64) -> usize {
+    use core::convert::TryFrom;
+    match usize::try_from(b) {
+        Ok(b) => a.saturating_sub(b),
+        Err(_) => 0,
+    }
+}
+
+#[inline(always)]
+#[cfg(feature = "std")]
+fn min_u64_usize(a: u64, b: usize) -> usize {
+    use core::convert::TryFrom;
+    match usize::try_from(a) {
+        Ok(a) => usize::min(a, b),
+        Err(_) => b,
+    }
+}
+
+/// Panic with a nice error message.
+#[cold]
+fn panic_advance(idx: usize, len: usize) -> ! {
+    panic!(
+        "advance out of bounds: the len is {} but advancing by {}",
+        len, idx
+    );
+}
+
+#[cold]
+fn panic_does_not_fit(size: usize, nbytes: usize) -> ! {
+    panic!(
+        "size too large: the integer type can fit {} bytes, but nbytes is {}",
+        size, nbytes
+    );
+}
+
+
\ No newline at end of file diff --git a/src/bytes/loom.rs.html b/src/bytes/loom.rs.html new file mode 100644 index 000000000..cc90586f2 --- /dev/null +++ b/src/bytes/loom.rs.html @@ -0,0 +1,62 @@ +loom.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
#[cfg(not(all(test, loom)))]
+pub(crate) mod sync {
+    pub(crate) mod atomic {
+        pub(crate) use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
+
+        pub(crate) trait AtomicMut<T> {
+            fn with_mut<F, R>(&mut self, f: F) -> R
+            where
+                F: FnOnce(&mut *mut T) -> R;
+        }
+
+        impl<T> AtomicMut<T> for AtomicPtr<T> {
+            fn with_mut<F, R>(&mut self, f: F) -> R
+            where
+                F: FnOnce(&mut *mut T) -> R,
+            {
+                f(self.get_mut())
+            }
+        }
+    }
+}
+
+#[cfg(all(test, loom))]
+pub(crate) mod sync {
+    pub(crate) mod atomic {
+        pub(crate) use loom::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
+
+        pub(crate) trait AtomicMut<T> {}
+    }
+}
+
+
\ No newline at end of file diff --git a/src/bytes/serde.rs.html b/src/bytes/serde.rs.html new file mode 100644 index 000000000..7946f8cdd --- /dev/null +++ b/src/bytes/serde.rs.html @@ -0,0 +1,180 @@ +serde.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+
use super::{Bytes, BytesMut};
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::{cmp, fmt};
+use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
+
+macro_rules! serde_impl {
+    ($ty:ident, $visitor_ty:ident, $from_slice:ident, $from_vec:ident) => {
+        impl Serialize for $ty {
+            #[inline]
+            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+            where
+                S: Serializer,
+            {
+                serializer.serialize_bytes(&self)
+            }
+        }
+
+        struct $visitor_ty;
+
+        impl<'de> de::Visitor<'de> for $visitor_ty {
+            type Value = $ty;
+
+            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+                formatter.write_str("byte array")
+            }
+
+            #[inline]
+            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
+            where
+                V: de::SeqAccess<'de>,
+            {
+                let len = cmp::min(seq.size_hint().unwrap_or(0), 4096);
+                let mut values: Vec<u8> = Vec::with_capacity(len);
+
+                while let Some(value) = seq.next_element()? {
+                    values.push(value);
+                }
+
+                Ok($ty::$from_vec(values))
+            }
+
+            #[inline]
+            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok($ty::$from_slice(v))
+            }
+
+            #[inline]
+            fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok($ty::$from_vec(v))
+            }
+
+            #[inline]
+            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok($ty::$from_slice(v.as_bytes()))
+            }
+
+            #[inline]
+            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+            where
+                E: de::Error,
+            {
+                Ok($ty::$from_vec(v.into_bytes()))
+            }
+        }
+
+        impl<'de> Deserialize<'de> for $ty {
+            #[inline]
+            fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                deserializer.deserialize_byte_buf($visitor_ty)
+            }
+        }
+    };
+}
+
+serde_impl!(Bytes, BytesVisitor, copy_from_slice, from);
+serde_impl!(BytesMut, BytesMutVisitor, from, from_vec);
+
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-002d5dd09d9a4f50.txt b/static.files/COPYRIGHT-002d5dd09d9a4f50.txt new file mode 100644 index 000000000..34e48134c --- /dev/null +++ b/static.files/COPYRIGHT-002d5dd09d9a4f50.txt @@ -0,0 +1,46 @@ +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. diff --git a/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt b/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt new file mode 100644 index 000000000..ff9afab06 --- /dev/null +++ b/static.files/FiraSans-LICENSE-1761dca11ffc8f19.txt @@ -0,0 +1,94 @@ +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 000000000..7a1e5fc54 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 000000000..e766e06cc Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 000000000..1866ad4bc Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt b/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt new file mode 100644 index 000000000..0bf46682b --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-2fe9ce67ec95245d.txt @@ -0,0 +1,99 @@ +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 000000000..462c34efc Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt b/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt new file mode 100644 index 000000000..07542572e --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-f554967dca0cf1dd.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 000000000..10b558e0b Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 000000000..5ec64eef0 Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 b/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 new file mode 100644 index 000000000..db57d2145 Binary files /dev/null and b/static.files/SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 b/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 new file mode 100644 index 000000000..1cbc021a3 Binary files /dev/null and b/static.files/SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md b/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md new file mode 100644 index 000000000..68ea18924 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-964d32dc04f20ca3.md @@ -0,0 +1,93 @@ +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 b/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 new file mode 100644 index 000000000..2db73fe2b Binary files /dev/null and b/static.files/SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2 differ diff --git a/static.files/ayu-c360e709a65bed99.css b/static.files/ayu-c360e709a65bed99.css new file mode 100644 index 000000000..2fa1fa39d --- /dev/null +++ b/static.files/ayu-c360e709a65bed99.css @@ -0,0 +1,285 @@ +/* +Based off of the Ayu theme +Original by Dempfi (https://github.com/dempfi/ayu) +*/ + +:root { + --main-background-color: #0f1419; + --main-color: #c5c5c5; + --settings-input-color: #ffb454; + --sidebar-background-color: #14191f; + --sidebar-background-color-hover: rgba(70, 70, 70, 0.33); + --code-block-background-color: #191f26; + --scrollbar-track-background-color: transparent; + --scrollbar-thumb-background-color: #5c6773; + --scrollbar-color: #5c6773 #24292f; + --headings-border-bottom-color: #5c6773; + --border-color: #5c6773; + --button-background-color: #141920; + --right-side-color: grey; + --code-attribute-color: #999; + --toggles-color: #999; + --search-input-focused-border-color: #5c6773; /* Same as `--border-color`. */ + --copy-path-button-color: #fff; + --copy-path-img-filter: invert(70%); + --copy-path-img-hover-filter: invert(100%); + --codeblock-error-hover-color: rgb(255, 0, 0); + --codeblock-error-color: rgba(255, 0, 0, .5); + --codeblock-ignore-hover-color: rgb(255, 142, 0); + --codeblock-ignore-color: rgba(255, 142, 0, .6); + --type-link-color: #ffa0a5; + --trait-link-color: #39afd7; + --assoc-item-link-color: #39afd7; + --function-link-color: #fdd687; + --macro-link-color: #a37acc; + --keyword-link-color: #39afd7; + --mod-link-color: #39afd7; + --link-color: #39afd7; + --sidebar-link-color: #53b1db; + --sidebar-current-link-background-color: transparent; + --search-result-link-focus-background-color: #3c3c3c; + --search-result-border-color: #aaa3; + --stab-background-color: #314559; + --stab-code-color: #e6e1cf; + --search-color: #fff; + --code-highlight-kw-color: #ff7733; + --code-highlight-kw-2-color: #ff7733; + --code-highlight-lifetime-color: #ff7733; + --code-highlight-prelude-color: #69f2df; + --code-highlight-prelude-val-color: #ff7733; + --code-highlight-number-color: #b8cc52; + --code-highlight-string-color: #b8cc52; + --code-highlight-literal-color: #ff7733; + --code-highlight-attribute-color: #e6e1cf; + --code-highlight-self-color: #36a3d9; + --code-highlight-macro-color: #a37acc; + --code-highlight-question-mark-color: #ff9011; + --code-highlight-comment-color: #788797; + --code-highlight-doc-comment-color: #a1ac88; + --example-line-numbers-border-color: none; + --src-line-numbers-span-color: #5c6773; + --src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06); + --test-arrow-color: #788797; + --test-arrow-background-color: rgba(57, 175, 215, 0.09); + --test-arrow-hover-color: #c5c5c5; + --test-arrow-hover-background-color: rgba(57, 175, 215, 0.368); + --target-background-color: rgba(255, 236, 164, 0.06); + --target-border-color: rgba(255, 180, 76, 0.85); + --rust-logo-filter: drop-shadow(1px 0 0px #fff) + drop-shadow(0 1px 0 #fff) + drop-shadow(-1px 0 0 #fff) + drop-shadow(0 -1px 0 #fff); + /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */ + --crate-search-div-filter: invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) + brightness(94%) contrast(94%); + --crate-search-div-hover-filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) + brightness(113%) contrast(76%); + --crate-search-hover-border: #e0e0e0; +} + +.slider { + background-color: #ccc; +} +.slider:before { + background-color: white; +} +input:focus + .slider { + box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); +} + +h1, h2, h3, h4 { + color: white; +} +h1 a { + color: #fff; +} +h4 { + border: none; +} + +.docblock code { + color: #ffb454; +} +.code-header { + color: #e6e1cf; +} +.docblock pre > code, pre > code { + color: #e6e1cf; +} +.item-info code { + color: #e6e1cf; +} +.docblock a > code { + color: #39AFD7 !important; +} +pre, .rustdoc.source .example-wrap { + color: #e6e1cf; +} + +.sidebar .current, +.sidebar a:hover { + color: #ffb44c; +} + +.sidebar-elems .location { + color: #ff7733; +} + +.src-line-numbers .line-highlighted { + color: #708090; + padding-right: 4px; + border-right: 1px solid #ffb44c; +} + +.search-results a:hover { + color: #fff !important; + background-color: #3c3c3c; +} + +.search-results a:focus { + color: #fff !important; + background-color: #3c3c3c; +} +.search-results a { + color: #0096cf; +} +.search-results a div.desc { + color: #c5c5c5; +} + +.content .item-info::before { color: #ccc; } + +.sidebar h2 a, +.sidebar h3 a { + color: white; +} +body.source .example-wrap pre.rust a { + background: #333; +} + +details.rustdoc-toggle > summary::before { + filter: invert(100%); +} + +.module-item .stab, +.import-item .stab { + color: #000; +} + +.result-name .primitive > i, .result-name .keyword > i { + color: #788797; +} + +.search-failed a { + color: #39AFD7; +} + +.tooltip::after { + background-color: #314559; + color: #c5c5c5; +} + +.tooltip::before { + border-color: transparent #314559 transparent transparent; +} + +.notable-traits-tooltiptext { + background-color: #314559; +} + +#titles > button.selected { + background-color: #141920 !important; + border-bottom: 1px solid #ffb44c !important; + border-top: none; +} + +#titles > button:not(.selected) { + background-color: transparent !important; + border: none; +} + +#titles > button:hover { + border-bottom: 1px solid rgba(242, 151, 24, 0.3); +} + +#titles > button > div.count { + color: #888; +} + +/* rules that this theme does not need to set, here to satisfy the rule checker */ +/* note that a lot of these are partially set in some way (meaning they are set +individually rather than as a group) */ +/* FIXME: these rules should be at the bottom of the file but currently must be +above the `@media (max-width: 700px)` rules due to a bug in the css checker */ +/* see https://github.com/rust-lang/rust/pull/71237#issuecomment-618170143 */ +pre.rust .lifetime {} +pre.rust .kw {} +#titles > button:hover, #titles > button.selected {} +pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {} +pre.rust .kw-2, pre.rust .prelude-ty {} + +kbd { + color: #c5c5c5; + background-color: #314559; + box-shadow: inset 0 -1px 0 #5c6773; +} + +#settings-menu > a, #help-button > a { + color: #fff; +} + +#settings-menu > a img { + filter: invert(100); +} + +#settings-menu > a:hover, #settings-menu > a:focus, +#help-button > a:hover, #help-button > a:focus { + border-color: #e0e0e0; +} + +.search-results .result-name span.alias { + color: #c5c5c5; +} +.search-results .result-name span.grey { + color: #999; +} + +#source-sidebar > .title { + color: #fff; +} +#source-sidebar div.files > a:hover, details.dir-entry summary:hover, +#source-sidebar div.files > a:focus, details.dir-entry summary:focus { + background-color: #14191f; + color: #ffb44c; +} +#source-sidebar div.files > a.selected { + background-color: #14191f; + color: #ffb44c; +} + +.scraped-example-list .scrape-help { + border-color: #aaa; + color: #eee; +} +.scraped-example-list .scrape-help:hover { + border-color: white; + color: white; +} +.scraped-example .example-wrap .rust span.highlight { + background: rgb(91, 59, 1); +} +.scraped-example .example-wrap .rust span.highlight.focus { + background: rgb(124, 75, 15); +} +.scraped-example:not(.expanded) .code-wrapper:before { + background: linear-gradient(to bottom, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0)); +} +.scraped-example:not(.expanded) .code-wrapper:after { + background: linear-gradient(to top, rgba(15, 20, 25, 1), rgba(15, 20, 25, 0)); +} +.toggle-line-inner { + background: #999; +} +.toggle-line:hover .toggle-line-inner { + background: #c5c5c5; +} diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 000000000..8adbd9963 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/dark-e2f4109f2e82e3af.css b/static.files/dark-e2f4109f2e82e3af.css new file mode 100644 index 000000000..43f8dd42a --- /dev/null +++ b/static.files/dark-e2f4109f2e82e3af.css @@ -0,0 +1,182 @@ +:root { + --main-background-color: #353535; + --main-color: #ddd; + --settings-input-color: #2196f3; + --sidebar-background-color: #505050; + --sidebar-background-color-hover: #676767; + --code-block-background-color: #2A2A2A; + --scrollbar-track-background-color: #717171; + --scrollbar-thumb-background-color: rgba(32, 34, 37, .6); + --scrollbar-color: rgba(32,34,37,.6) #5a5a5a; + --headings-border-bottom-color: #d2d2d2; + --border-color: #e0e0e0; + --button-background-color: #f0f0f0; + --right-side-color: grey; + --code-attribute-color: #999; + --toggles-color: #999; + --search-input-focused-border-color: #008dfd; + --copy-path-button-color: #999; + --copy-path-img-filter: invert(50%); + --copy-path-img-hover-filter: invert(65%); + --codeblock-error-hover-color: rgb(255, 0, 0); + --codeblock-error-color: rgba(255, 0, 0, .5); + --codeblock-ignore-hover-color: rgb(255, 142, 0); + --codeblock-ignore-color: rgba(255, 142, 0, .6); + --type-link-color: #2dbfb8; + --trait-link-color: #b78cf2; + --assoc-item-link-color: #d2991d; + --function-link-color: #2bab63; + --macro-link-color: #09bd00; + --keyword-link-color: #d2991d; + --mod-link-color: #d2991d; + --link-color: #d2991d; + --sidebar-link-color: #fdbf35; + --sidebar-current-link-background-color: #444; + --search-result-link-focus-background-color: #616161; + --search-result-border-color: #aaa3; + --stab-background-color: #314559; + --stab-code-color: #e6e1cf; + --search-color: #111; + --code-highlight-kw-color: #ab8ac1; + --code-highlight-kw-2-color: #769acb; + --code-highlight-lifetime-color: #d97f26; + --code-highlight-prelude-color: #769acb; + --code-highlight-prelude-val-color: #ee6868; + --code-highlight-number-color: #83a300; + --code-highlight-string-color: #83a300; + --code-highlight-literal-color: #ee6868; + --code-highlight-attribute-color: #ee6868; + --code-highlight-self-color: #ee6868; + --code-highlight-macro-color: #3e999f; + --code-highlight-question-mark-color: #ff9011; + --code-highlight-comment-color: #8d8d8b; + --code-highlight-doc-comment-color: #8ca375; + --example-line-numbers-border-color: #4a4949; + --src-line-numbers-span-color: #3b91e2; + --src-line-number-highlighted-background-color: #0a042f; + --test-arrow-color: #dedede; + --test-arrow-background-color: rgba(78, 139, 202, 0.2); + --test-arrow-hover-color: #dedede; + --test-arrow-hover-background-color: #4e8bca; + --target-background-color: #494a3d; + --target-border-color: #bb7410; + --rust-logo-filter: drop-shadow(1px 0 0px #fff) + drop-shadow(0 1px 0 #fff) + drop-shadow(-1px 0 0 #fff) + drop-shadow(0 -1px 0 #fff); + /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */ + --crate-search-div-filter: invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) + brightness(90%) contrast(90%); + --crate-search-div-hover-filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) + brightness(100%) contrast(91%); + --crate-search-hover-border: #2196f3; +} + +.slider { + background-color: #ccc; +} +.slider:before { + background-color: white; +} +input:focus + .slider { + box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); +} + +.content .item-info::before { color: #ccc; } + +body.source .example-wrap pre.rust a { + background: #333; +} + +details.rustdoc-toggle > summary::before { + filter: invert(100%); +} + +.search-failed a { + color: #0089ff; +} + +.tooltip::after { + background-color: #000; + color: #fff; + border-color: #000; +} + +.tooltip::before { + border-color: transparent black transparent transparent; +} + +.notable-traits-tooltiptext { + background-color: #111; +} + +#titles > button:not(.selected) { + background-color: #252525; + border-top-color: #252525; +} + +#titles > button:hover, #titles > button.selected { + border-top-color: #0089ff; + background-color: #353535; +} + +#titles > button > div.count { + color: #888; +} + +kbd { + color: #000; + background-color: #fafbfc; + box-shadow: inset 0 -1px 0 #c6cbd1; +} + +#settings-menu > a, #help-button > a { + color: #000; +} + +#settings-menu > a:hover, #settings-menu > a:focus, +#help-button > a:hover, #help-button > a:focus { + border-color: #ffb900; +} + +.search-results .result-name span.alias { + color: #fff; +} +.search-results .result-name span.grey { + color: #ccc; +} + +#source-sidebar div.files > a:hover, details.dir-entry summary:hover, +#source-sidebar div.files > a:focus, details.dir-entry summary:focus { + background-color: #444; +} +#source-sidebar div.files > a.selected { + background-color: #333; +} + +.scraped-example-list .scrape-help { + border-color: #aaa; + color: #eee; +} +.scraped-example-list .scrape-help:hover { + border-color: white; + color: white; +} +.scraped-example .example-wrap .rust span.highlight { + background: rgb(91, 59, 1); +} +.scraped-example .example-wrap .rust span.highlight.focus { + background: rgb(124, 75, 15); +} +.scraped-example:not(.expanded) .code-wrapper:before { + background: linear-gradient(to bottom, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0)); +} +.scraped-example:not(.expanded) .code-wrapper:after { + background: linear-gradient(to top, rgba(53, 53, 53, 1), rgba(53, 53, 53, 0)); +} +.toggle-line-inner { + background: #999; +} +.toggle-line:hover .toggle-line-inner { + background: #c5c5c5; +} diff --git a/static.files/down-arrow-927217e04c7463ac.svg b/static.files/down-arrow-927217e04c7463ac.svg new file mode 100644 index 000000000..5d76a64e9 --- /dev/null +++ b/static.files/down-arrow-927217e04c7463ac.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 000000000..ea4b45cae Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 000000000..8b34b5119 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 000000000..69b8613ce Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/light-777f3e9583f8c92d.css b/static.files/light-777f3e9583f8c92d.css new file mode 100644 index 000000000..c8c5289ab --- /dev/null +++ b/static.files/light-777f3e9583f8c92d.css @@ -0,0 +1,173 @@ +:root { + --main-background-color: white; + --main-color: black; + --settings-input-color: #2196f3; + --sidebar-background-color: #F5F5F5; + --sidebar-background-color-hover: #E0E0E0; + --code-block-background-color: #F5F5F5; + --scrollbar-track-background-color: #dcdcdc; + --scrollbar-thumb-background-color: rgba(36, 37, 39, 0.6); + --scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9; + --headings-border-bottom-color: #ddd; + --border-color: #e0e0e0; + --button-background-color: #fff; + --right-side-color: grey; + --code-attribute-color: #999; + --toggles-color: #999; + --search-input-focused-border-color: #66afe9; + --copy-path-button-color: #999; + --copy-path-img-filter: invert(50%); + --copy-path-img-hover-filter: invert(35%); + --codeblock-error-hover-color: rgb(255, 0, 0); + --codeblock-error-color: rgba(255, 0, 0, .5); + --codeblock-ignore-hover-color: rgb(255, 142, 0); + --codeblock-ignore-color: rgba(255, 142, 0, .6); + --type-link-color: #ad378a; + --trait-link-color: #6e4fc9; + --assoc-item-link-color: #3873ad; + --function-link-color: #ad7c37; + --macro-link-color: #068000; + --keyword-link-color: #3873ad; + --mod-link-color: #3873ad; + --link-color: #3873ad; + --sidebar-link-color: #356da4; + --sidebar-current-link-background-color: #fff; + --search-result-link-focus-background-color: #ccc; + --search-result-border-color: #aaa3; + --stab-background-color: #fff5d6; + --stab-code-color: #000; + --search-color: #000; + --code-highlight-kw-color: #8959a8; + --code-highlight-kw-2-color: #4271ae; + --code-highlight-lifetime-color: #b76514; + --code-highlight-prelude-color: #4271ae; + --code-highlight-prelude-val-color: #c82829; + --code-highlight-number-color: #718c00; + --code-highlight-string-color: #718c00; + --code-highlight-literal-color: #c82829; + --code-highlight-attribute-color: #c82829; + --code-highlight-self-color: #c82829; + --code-highlight-macro-color: #3e999f; + --code-highlight-question-mark-color: #ff9011; + --code-highlight-comment-color: #8e908c; + --code-highlight-doc-comment-color: #4d4d4c; + --example-line-numbers-border-color: #c7c7c7; + --src-line-numbers-span-color: #c67e2d; + --src-line-number-highlighted-background-color: #fdffd3; + --test-arrow-color: #f5f5f5; + --test-arrow-background-color: rgba(78, 139, 202, 0.2); + --test-arrow-hover-color: #f5f5f5; + --test-arrow-hover-background-color: #4e8bca; + --target-background-color: #fdFfd3; + --target-border-color: #ad7c37; + --rust-logo-filter: initial; + /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */ + --crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) + brightness(114%) contrast(76%); + --crate-search-div-hover-filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) + brightness(96%) contrast(93%); + --crate-search-hover-border: #717171; +} + +.slider { + background-color: #ccc; +} +.slider:before { + background-color: white; +} +input:focus + .slider { + box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3); +} + +.content .item-info::before { color: #ccc; } + +body.source .example-wrap pre.rust a { + background: #eee; +} + +.search-failed a { + color: #3873AD; +} + +.tooltip::after { + background-color: #000; + color: #fff; +} + +.tooltip::before { + border-color: transparent black transparent transparent; +} + +.notable-traits-tooltiptext { + background-color: #eee; +} + +#titles > button:not(.selected) { + background-color: #e6e6e6; + border-top-color: #e6e6e6; +} + +#titles > button:hover, #titles > button.selected { + background-color: #ffffff; + border-top-color: #0089ff; +} + +#titles > button > div.count { + color: #888; +} + +kbd { + color: #000; + background-color: #fafbfc; + box-shadow: inset 0 -1px 0 #c6cbd1; +} + +#settings-menu > a, #help-button > a { + color: #000; +} + +#settings-menu > a:hover, #settings-menu > a:focus, +#help-button > a:hover, #help-button > a:focus { + border-color: #717171; +} + +.search-results .result-name span.alias { + color: #000; +} +.search-results .result-name span.grey { + color: #999; +} + +#source-sidebar div.files > a:hover, details.dir-entry summary:hover, +#source-sidebar div.files > a:focus, details.dir-entry summary:focus { + background-color: #E0E0E0; +} +#source-sidebar div.files > a.selected { + background-color: #fff; +} +.scraped-example-list .scrape-help { + border-color: #555; + color: #333; +} +.scraped-example-list .scrape-help:hover { + border-color: black; + color: black; +} +.scraped-example .example-wrap .rust span.highlight { + background: #fcffd6; +} +.scraped-example .example-wrap .rust span.highlight.focus { + background: #f6fdb0; +} +.scraped-example:not(.expanded) .code-wrapper:before { + background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); +} +.scraped-example:not(.expanded) .code-wrapper:after { + background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)); +} +.toggle-line-inner { + background: #ccc; +} +.toggle-line:hover .toggle-line-inner { + background: #999; +} diff --git a/static.files/main-c2d2a5dbaed13e6b.js b/static.files/main-c2d2a5dbaed13e6b.js new file mode 100644 index 000000000..0426774e8 --- /dev/null +++ b/static.files/main-c2d2a5dbaed13e6b.js @@ -0,0 +1,1150 @@ +// Local js definitions: +/* global addClass, getSettingValue, hasClass, searchState */ +/* global onEach, onEachLazy, removeClass */ + +"use strict"; + +// Get a value from the rustdoc-vars div, which is used to convey data from +// Rust to the JS. If there is no such element, return null. +function getVar(name) { + const el = document.getElementById("rustdoc-vars"); + if (el) { + return el.attributes["data-" + name].value; + } else { + return null; + } +} + +// Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL +// for a resource under the root-path, with the resource-suffix. +function resourcePath(basename, extension) { + return getVar("root-path") + basename + getVar("resource-suffix") + extension; +} + +function hideMain() { + addClass(document.getElementById(MAIN_ID), "hidden"); +} + +function showMain() { + removeClass(document.getElementById(MAIN_ID), "hidden"); +} + +function elemIsInParent(elem, parent) { + while (elem && elem !== document.body) { + if (elem === parent) { + return true; + } + elem = elem.parentElement; + } + return false; +} + +function blurHandler(event, parentElem, hideCallback) { + if (!elemIsInParent(document.activeElement, parentElem) && + !elemIsInParent(event.relatedTarget, parentElem) + ) { + hideCallback(); + } +} + +(function() { + window.rootPath = getVar("root-path"); + window.currentCrate = getVar("current-crate"); +}()); + +function setMobileTopbar() { + // FIXME: It would be nicer to generate this text content directly in HTML, + // but with the current code it's hard to get the right information in the right place. + const mobileLocationTitle = document.querySelector(".mobile-topbar h2"); + const locationTitle = document.querySelector(".sidebar h2.location"); + if (mobileLocationTitle && locationTitle) { + mobileLocationTitle.innerHTML = locationTitle.innerHTML; + } +} + +// Gets the human-readable string for the virtual-key code of the +// given KeyboardEvent, ev. +// +// This function is meant as a polyfill for KeyboardEvent#key, +// since it is not supported in IE 11 or Chrome for Android. We also test for +// KeyboardEvent#keyCode because the handleShortcut handler is +// also registered for the keydown event, because Blink doesn't fire +// keypress on hitting the Escape key. +// +// So I guess you could say things are getting pretty interoperable. +function getVirtualKey(ev) { + if ("key" in ev && typeof ev.key !== "undefined") { + return ev.key; + } + + const c = ev.charCode || ev.keyCode; + if (c === 27) { + return "Escape"; + } + return String.fromCharCode(c); +} + +const MAIN_ID = "main-content"; +const SETTINGS_BUTTON_ID = "settings-menu"; +const ALTERNATIVE_DISPLAY_ID = "alternative-display"; +const NOT_DISPLAYED_ID = "not-displayed"; +const HELP_BUTTON_ID = "help-button"; + +function getSettingsButton() { + return document.getElementById(SETTINGS_BUTTON_ID); +} + +function getHelpButton() { + return document.getElementById(HELP_BUTTON_ID); +} + +// Returns the current URL without any query parameter or hash. +function getNakedUrl() { + return window.location.href.split("?")[0].split("#")[0]; +} + +/** + * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode` + * doesn't have a parent node. + * + * @param {HTMLElement} newNode + * @param {HTMLElement} referenceNode + */ +function insertAfter(newNode, referenceNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); +} + +/** + * This function creates a new `
` with the given `id` and `classes` if it doesn't already + * exist. + * + * More information about this in `switchDisplayedElement` documentation. + * + * @param {string} id + * @param {string} classes + */ +function getOrCreateSection(id, classes) { + let el = document.getElementById(id); + + if (!el) { + el = document.createElement("section"); + el.id = id; + el.className = classes; + insertAfter(el, document.getElementById(MAIN_ID)); + } + return el; +} + +/** + * Returns the `
` element which contains the displayed element. + * + * @return {HTMLElement} + */ +function getAlternativeDisplayElem() { + return getOrCreateSection(ALTERNATIVE_DISPLAY_ID, "content hidden"); +} + +/** + * Returns the `
` element which contains the not-displayed elements. + * + * @return {HTMLElement} + */ +function getNotDisplayedElem() { + return getOrCreateSection(NOT_DISPLAYED_ID, "hidden"); +} + +/** + * To nicely switch between displayed "extra" elements (such as search results or settings menu) + * and to alternate between the displayed and not displayed elements, we hold them in two different + * `
` elements. They work in pair: one holds the hidden elements while the other + * contains the displayed element (there can be only one at the same time!). So basically, we switch + * elements between the two `
` elements. + * + * @param {HTMLElement} elemToDisplay + */ +function switchDisplayedElement(elemToDisplay) { + const el = getAlternativeDisplayElem(); + + if (el.children.length > 0) { + getNotDisplayedElem().appendChild(el.firstElementChild); + } + if (elemToDisplay === null) { + addClass(el, "hidden"); + showMain(); + return; + } + el.appendChild(elemToDisplay); + hideMain(); + removeClass(el, "hidden"); +} + +function browserSupportsHistoryApi() { + return window.history && typeof window.history.pushState === "function"; +} + +// eslint-disable-next-line no-unused-vars +function loadCss(cssUrl) { + const link = document.createElement("link"); + link.href = cssUrl; + link.type = "text/css"; + link.rel = "stylesheet"; + document.getElementsByTagName("head")[0].appendChild(link); +} + +(function() { + const isHelpPage = window.location.pathname.endsWith("/help.html"); + + function loadScript(url) { + const script = document.createElement("script"); + script.src = url; + document.head.append(script); + } + + getSettingsButton().onclick = event => { + if (event.ctrlKey || event.altKey || event.metaKey) { + return; + } + addClass(getSettingsButton(), "rotate"); + event.preventDefault(); + // Sending request for the CSS and the JS files at the same time so it will + // hopefully be loaded when the JS will generate the settings content. + loadCss(getVar("static-root-path") + getVar("settings-css")); + loadScript(getVar("static-root-path") + getVar("settings-js")); + }; + + window.searchState = { + loadingText: "Loading search results...", + input: document.getElementsByClassName("search-input")[0], + outputElement: () => { + let el = document.getElementById("search"); + if (!el) { + el = document.createElement("section"); + el.id = "search"; + getNotDisplayedElem().appendChild(el); + } + return el; + }, + title: document.title, + titleBeforeSearch: document.title, + timeout: null, + // On the search screen, so you remain on the last tab you opened. + // + // 0 for "In Names" + // 1 for "In Parameters" + // 2 for "In Return Types" + currentTab: 0, + // tab and back preserves the element that was focused. + focusedByTab: [null, null, null], + clearInputTimeout: () => { + if (searchState.timeout !== null) { + clearTimeout(searchState.timeout); + searchState.timeout = null; + } + }, + isDisplayed: () => searchState.outputElement().parentElement.id === ALTERNATIVE_DISPLAY_ID, + // Sets the focus on the search bar at the top of the page + focus: () => { + searchState.input.focus(); + }, + // Removes the focus from the search bar. + defocus: () => { + searchState.input.blur(); + }, + showResults: search => { + if (search === null || typeof search === "undefined") { + search = searchState.outputElement(); + } + switchDisplayedElement(search); + searchState.mouseMovedAfterSearch = false; + document.title = searchState.title; + }, + hideResults: () => { + switchDisplayedElement(null); + document.title = searchState.titleBeforeSearch; + // We also remove the query parameter from the URL. + if (browserSupportsHistoryApi()) { + history.replaceState(null, window.currentCrate + " - Rust", + getNakedUrl() + window.location.hash); + } + }, + getQueryStringParams: () => { + const params = {}; + window.location.search.substring(1).split("&"). + map(s => { + const pair = s.split("="); + params[decodeURIComponent(pair[0])] = + typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]); + }); + return params; + }, + setup: () => { + const search_input = searchState.input; + if (!searchState.input) { + return; + } + let searchLoaded = false; + function loadSearch() { + if (!searchLoaded) { + searchLoaded = true; + loadScript(getVar("static-root-path") + getVar("search-js")); + loadScript(resourcePath("search-index", ".js")); + } + } + + search_input.addEventListener("focus", () => { + search_input.origPlaceholder = search_input.placeholder; + search_input.placeholder = "Type your search here."; + loadSearch(); + }); + + if (search_input.value !== "") { + loadSearch(); + } + + const params = searchState.getQueryStringParams(); + if (params.search !== undefined) { + const search = searchState.outputElement(); + search.innerHTML = "

" + + searchState.loadingText + "

"; + searchState.showResults(search); + loadSearch(); + } + }, + }; + + function getPageId() { + if (window.location.hash) { + const tmp = window.location.hash.replace(/^#/, ""); + if (tmp.length > 0) { + return tmp; + } + } + return null; + } + + const toggleAllDocsId = "toggle-all-docs"; + let savedHash = ""; + + function handleHashes(ev) { + if (ev !== null && searchState.isDisplayed() && ev.newURL) { + // This block occurs when clicking on an element in the navbar while + // in a search. + switchDisplayedElement(null); + const hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); + if (browserSupportsHistoryApi()) { + // `window.location.search`` contains all the query parameters, not just `search`. + history.replaceState(null, "", + getNakedUrl() + window.location.search + "#" + hash); + } + const elem = document.getElementById(hash); + if (elem) { + elem.scrollIntoView(); + } + } + // This part is used in case an element is not visible. + if (savedHash !== window.location.hash) { + savedHash = window.location.hash; + if (savedHash.length === 0) { + return; + } + expandSection(savedHash.slice(1)); // we remove the '#' + } + } + + function onHashChange(ev) { + // If we're in mobile mode, we should hide the sidebar in any case. + hideSidebar(); + handleHashes(ev); + } + + function openParentDetails(elem) { + while (elem) { + if (elem.tagName === "DETAILS") { + elem.open = true; + } + elem = elem.parentNode; + } + } + + function expandSection(id) { + openParentDetails(document.getElementById(id)); + } + + function handleEscape(ev) { + searchState.clearInputTimeout(); + switchDisplayedElement(null); + if (browserSupportsHistoryApi()) { + history.replaceState(null, window.currentCrate + " - Rust", + getNakedUrl() + window.location.hash); + } + ev.preventDefault(); + searchState.defocus(); + window.hidePopoverMenus(); + } + + function handleShortcut(ev) { + // Don't interfere with browser shortcuts + const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; + if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) { + return; + } + + if (document.activeElement.tagName === "INPUT" && + document.activeElement.type !== "checkbox") { + switch (getVirtualKey(ev)) { + case "Escape": + handleEscape(ev); + break; + } + } else { + switch (getVirtualKey(ev)) { + case "Escape": + handleEscape(ev); + break; + + case "s": + case "S": + ev.preventDefault(); + searchState.focus(); + break; + + case "+": + ev.preventDefault(); + expandAllDocs(); + break; + case "-": + ev.preventDefault(); + collapseAllDocs(); + break; + + case "?": + showHelp(); + break; + + default: + break; + } + } + } + + document.addEventListener("keypress", handleShortcut); + document.addEventListener("keydown", handleShortcut); + + function addSidebarItems() { + if (!window.SIDEBAR_ITEMS) { + return; + } + const sidebar = document.getElementsByClassName("sidebar-elems")[0]; + + /** + * Append to the sidebar a "block" of links - a heading along with a list (`
    `) of items. + * + * @param {string} shortty - A short type name, like "primitive", "mod", or "macro" + * @param {string} id - The HTML id of the corresponding section on the module page. + * @param {string} longty - A long, capitalized, plural name, like "Primitive Types", + * "Modules", or "Macros". + */ + function block(shortty, id, longty) { + const filtered = window.SIDEBAR_ITEMS[shortty]; + if (!filtered) { + return; + } + + const h3 = document.createElement("h3"); + h3.innerHTML = `${longty}`; + const ul = document.createElement("ul"); + ul.className = "block " + shortty; + + for (const item of filtered) { + const name = item[0]; + const desc = item[1]; // can be null + + let path; + if (shortty === "mod") { + path = name + "/index.html"; + } else { + path = shortty + "." + name + ".html"; + } + const current_page = document.location.href.split("/").pop(); + const link = document.createElement("a"); + link.href = path; + link.title = desc; + if (path === current_page) { + link.className = "current"; + } + link.textContent = name; + const li = document.createElement("li"); + li.appendChild(link); + ul.appendChild(li); + } + sidebar.appendChild(h3); + sidebar.appendChild(ul); + } + + if (sidebar) { + block("primitive", "primitives", "Primitive Types"); + block("mod", "modules", "Modules"); + block("macro", "macros", "Macros"); + block("struct", "structs", "Structs"); + block("enum", "enums", "Enums"); + block("union", "unions", "Unions"); + block("constant", "constants", "Constants"); + block("static", "static", "Statics"); + block("trait", "traits", "Traits"); + block("fn", "functions", "Functions"); + block("type", "types", "Type Definitions"); + block("foreigntype", "foreign-types", "Foreign Types"); + block("keyword", "keywords", "Keywords"); + block("traitalias", "trait-aliases", "Trait Aliases"); + } + } + + window.register_implementors = imp => { + const implementors = document.getElementById("implementors-list"); + const synthetic_implementors = document.getElementById("synthetic-implementors-list"); + const inlined_types = new Set(); + + const TEXT_IDX = 0; + const SYNTHETIC_IDX = 1; + const TYPES_IDX = 2; + + if (synthetic_implementors) { + // This `inlined_types` variable is used to avoid having the same implementation + // showing up twice. For example "String" in the "Sync" doc page. + // + // By the way, this is only used by and useful for traits implemented automatically + // (like "Send" and "Sync"). + onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => { + const aliases = el.getAttribute("data-aliases"); + if (!aliases) { + return; + } + aliases.split(",").forEach(alias => { + inlined_types.add(alias); + }); + }); + } + + let currentNbImpls = implementors.getElementsByClassName("impl").length; + const traitName = document.querySelector("h1.fqn > .trait").textContent; + const baseIdName = "impl-" + traitName + "-"; + const libs = Object.getOwnPropertyNames(imp); + // We don't want to include impls from this JS file, when the HTML already has them. + // The current crate should always be ignored. Other crates that should also be + // ignored are included in the attribute `data-ignore-extern-crates`. + const script = document + .querySelector("script[data-ignore-extern-crates]"); + const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; + for (const lib of libs) { + if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { + continue; + } + const structs = imp[lib]; + + struct_loop: + for (const struct of structs) { + const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors; + + // The types list is only used for synthetic impls. + // If this changes, `main.js` and `write_shared.rs` both need changed. + if (struct[SYNTHETIC_IDX]) { + for (const struct_type of struct[TYPES_IDX]) { + if (inlined_types.has(struct_type)) { + continue struct_loop; + } + inlined_types.add(struct_type); + } + } + + const code = document.createElement("h3"); + code.innerHTML = struct[TEXT_IDX]; + addClass(code, "code-header"); + + onEachLazy(code.getElementsByTagName("a"), elem => { + const href = elem.getAttribute("href"); + + if (href && href.indexOf("http") !== 0) { + elem.setAttribute("href", window.rootPath + href); + } + }); + + const currentId = baseIdName + currentNbImpls; + const anchor = document.createElement("a"); + anchor.href = "#" + currentId; + addClass(anchor, "anchor"); + + const display = document.createElement("div"); + display.id = currentId; + addClass(display, "impl"); + display.appendChild(anchor); + display.appendChild(code); + list.appendChild(display); + currentNbImpls += 1; + } + } + }; + if (window.pending_implementors) { + window.register_implementors(window.pending_implementors); + } + + function addSidebarCrates() { + if (!window.ALL_CRATES) { + return; + } + const sidebarElems = document.getElementsByClassName("sidebar-elems")[0]; + if (!sidebarElems) { + return; + } + // Draw a convenient sidebar of known crates if we have a listing + const h3 = document.createElement("h3"); + h3.innerHTML = "Crates"; + const ul = document.createElement("ul"); + ul.className = "block crate"; + + for (const crate of window.ALL_CRATES) { + const link = document.createElement("a"); + link.href = window.rootPath + crate + "/index.html"; + if (window.rootPath !== "./" && crate === window.currentCrate) { + link.className = "current"; + } + link.textContent = crate; + + const li = document.createElement("li"); + li.appendChild(link); + ul.appendChild(li); + } + sidebarElems.appendChild(h3); + sidebarElems.appendChild(ul); + } + + function expandAllDocs() { + const innerToggle = document.getElementById(toggleAllDocsId); + removeClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { + if (!hasClass(e, "type-contents-toggle")) { + e.open = true; + } + }); + innerToggle.title = "collapse all docs"; + innerToggle.children[0].innerText = "\u2212"; // "\u2212" is "−" minus sign + } + + function collapseAllDocs() { + const innerToggle = document.getElementById(toggleAllDocsId); + addClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { + if (e.parentNode.id !== "implementations-list" || + (!hasClass(e, "implementors-toggle") && + !hasClass(e, "type-contents-toggle")) + ) { + e.open = false; + } + }); + innerToggle.title = "expand all docs"; + innerToggle.children[0].innerText = "+"; + } + + function toggleAllDocs() { + const innerToggle = document.getElementById(toggleAllDocsId); + if (!innerToggle) { + return; + } + if (hasClass(innerToggle, "will-expand")) { + expandAllDocs(); + } else { + collapseAllDocs(); + } + } + + (function() { + const toggles = document.getElementById(toggleAllDocsId); + if (toggles) { + toggles.onclick = toggleAllDocs; + } + + const hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; + const hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true"; + const hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; + + function setImplementorsTogglesOpen(id, open) { + const list = document.getElementById(id); + if (list !== null) { + onEachLazy(list.getElementsByClassName("implementors-toggle"), e => { + e.open = open; + }); + } + } + + if (hideImplementations) { + setImplementorsTogglesOpen("trait-implementations-list", false); + setImplementorsTogglesOpen("blanket-implementations-list", false); + } + + onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { + if (!hideLargeItemContents && hasClass(e, "type-contents-toggle")) { + e.open = true; + } + if (hideMethodDocs && hasClass(e, "method-toggle")) { + e.open = false; + } + + }); + + const pageId = getPageId(); + if (pageId !== null) { + expandSection(pageId); + } + }()); + + window.rustdoc_add_line_numbers_to_examples = () => { + onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => { + const parent = x.parentNode; + const line_numbers = parent.querySelectorAll(".example-line-numbers"); + if (line_numbers.length > 0) { + return; + } + const count = x.textContent.split("\n").length; + const elems = []; + for (let i = 0; i < count; ++i) { + elems.push(i + 1); + } + const node = document.createElement("pre"); + addClass(node, "example-line-numbers"); + node.innerHTML = elems.join("\n"); + parent.insertBefore(node, x); + }); + }; + + window.rustdoc_remove_line_numbers_from_examples = () => { + onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => { + const parent = x.parentNode; + const line_numbers = parent.querySelectorAll(".example-line-numbers"); + for (const node of line_numbers) { + parent.removeChild(node); + } + }); + }; + + (function() { + // To avoid checking on "rustdoc-line-numbers" value on every loop... + if (getSettingValue("line-numbers") === "true") { + window.rustdoc_add_line_numbers_to_examples(); + } + }()); + + let oldSidebarScrollPosition = null; + + // Scroll locking used both here and in source-script.js + + window.rustdocMobileScrollLock = function() { + const mobile_topbar = document.querySelector(".mobile-topbar"); + if (window.innerWidth <= window.RUSTDOC_MOBILE_BREAKPOINT) { + // This is to keep the scroll position on mobile. + oldSidebarScrollPosition = window.scrollY; + document.body.style.width = `${document.body.offsetWidth}px`; + document.body.style.position = "fixed"; + document.body.style.top = `-${oldSidebarScrollPosition}px`; + if (mobile_topbar) { + mobile_topbar.style.top = `${oldSidebarScrollPosition}px`; + mobile_topbar.style.position = "relative"; + } + } else { + oldSidebarScrollPosition = null; + } + }; + + window.rustdocMobileScrollUnlock = function() { + const mobile_topbar = document.querySelector(".mobile-topbar"); + if (oldSidebarScrollPosition !== null) { + // This is to keep the scroll position on mobile. + document.body.style.width = ""; + document.body.style.position = ""; + document.body.style.top = ""; + if (mobile_topbar) { + mobile_topbar.style.top = ""; + mobile_topbar.style.position = ""; + } + // The scroll position is lost when resetting the style, hence why we store it in + // `oldSidebarScrollPosition`. + window.scrollTo(0, oldSidebarScrollPosition); + oldSidebarScrollPosition = null; + } + }; + + function showSidebar() { + window.rustdocMobileScrollLock(); + const sidebar = document.getElementsByClassName("sidebar")[0]; + addClass(sidebar, "shown"); + } + + function hideSidebar() { + window.rustdocMobileScrollUnlock(); + const sidebar = document.getElementsByClassName("sidebar")[0]; + removeClass(sidebar, "shown"); + } + + window.addEventListener("resize", () => { + if (window.innerWidth > window.RUSTDOC_MOBILE_BREAKPOINT && + oldSidebarScrollPosition !== null) { + // If the user opens the sidebar in "mobile" mode, and then grows the browser window, + // we need to switch away from mobile mode and make the main content area scrollable. + hideSidebar(); + } + if (window.CURRENT_NOTABLE_ELEMENT) { + // As a workaround to the behavior of `contains: layout` used in doc togglers, the + // notable traits popup is positioned using javascript. + // + // This means when the window is resized, we need to redo the layout. + const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE; + const force_visible = base.NOTABLE_FORCE_VISIBLE; + hideNotable(); + if (force_visible) { + showNotable(base); + base.NOTABLE_FORCE_VISIBLE = true; + } + } + }); + + function handleClick(id, f) { + const elem = document.getElementById(id); + if (elem) { + elem.addEventListener("click", f); + } + } + handleClick(MAIN_ID, () => { + hideSidebar(); + }); + + onEachLazy(document.getElementsByTagName("a"), el => { + // For clicks on internal links ( tags with a hash property), we expand the section we're + // jumping to *before* jumping there. We can't do this in onHashChange, because it changes + // the height of the document so we wind up scrolled to the wrong place. + if (el.hash) { + el.addEventListener("click", () => { + expandSection(el.hash.slice(1)); + hideSidebar(); + }); + } + }); + + onEachLazy(document.querySelectorAll(".rustdoc-toggle > summary:not(.hideme)"), el => { + el.addEventListener("click", e => { + if (e.target.tagName !== "SUMMARY" && e.target.tagName !== "A") { + e.preventDefault(); + } + }); + }); + + function showNotable(e) { + if (!window.NOTABLE_TRAITS) { + const data = document.getElementById("notable-traits-data"); + if (data) { + window.NOTABLE_TRAITS = JSON.parse(data.innerText); + } else { + throw new Error("showNotable() called on page without any notable traits!"); + } + } + if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) { + // Make this function idempotent. + return; + } + hideNotable(); + const ty = e.getAttribute("data-ty"); + const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0]; + const wrapper = document.createElement("div"); + wrapper.innerHTML = "
    " + window.NOTABLE_TRAITS[ty] + "
    "; + wrapper.className = "notable-traits-tooltiptext"; + tooltip.appendChild(wrapper); + const pos = wrapper.getBoundingClientRect(); + tooltip.removeChild(wrapper); + wrapper.style.top = (pos.top + window.scrollY) + "px"; + wrapper.style.left = (pos.left + window.scrollX) + "px"; + wrapper.style.width = pos.width + "px"; + const body = document.getElementsByTagName("body")[0]; + body.appendChild(wrapper); + window.CURRENT_NOTABLE_ELEMENT = wrapper; + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e; + wrapper.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) { + hideNotable(); + } + }; + } + + function hideNotable() { + if (window.CURRENT_NOTABLE_ELEMENT) { + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; + const body = document.getElementsByTagName("body")[0]; + body.removeChild(window.CURRENT_NOTABLE_ELEMENT); + window.CURRENT_NOTABLE_ELEMENT = null; + } + } + + onEachLazy(document.getElementsByClassName("notable-traits"), e => { + e.onclick = function() { + this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true; + if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) { + hideNotable(); + } else { + showNotable(this); + } + }; + e.onpointerenter = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + showNotable(this); + }; + e.onpointerleave = function(ev) { + // If this is a synthetic touch event, ignore it. A click event will be along shortly. + if (ev.pointerType !== "mouse") { + return; + } + if (!this.NOTABLE_FORCE_VISIBLE && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) { + hideNotable(); + } + }; + }); + + const sidebar_menu_toggle = document.getElementsByClassName("sidebar-menu-toggle")[0]; + if (sidebar_menu_toggle) { + sidebar_menu_toggle.addEventListener("click", () => { + const sidebar = document.getElementsByClassName("sidebar")[0]; + if (!hasClass(sidebar, "shown")) { + showSidebar(); + } else { + hideSidebar(); + } + }); + } + + function helpBlurHandler(event) { + blurHandler(event, getHelpButton(), window.hidePopoverMenus); + } + + function buildHelpMenu() { + const book_info = document.createElement("span"); + book_info.className = "top"; + book_info.innerHTML = "You can find more information in \ +
    the rustdoc book."; + + const shortcuts = [ + ["?", "Show this help dialog"], + ["S", "Focus the search field"], + ["↑", "Move up in search results"], + ["↓", "Move down in search results"], + ["← / →", "Switch result tab (when results focused)"], + ["⏎", "Go to active search result"], + ["+", "Expand all sections"], + ["-", "Collapse all sections"], + ].map(x => "
    " + + x[0].split(" ") + .map((y, index) => ((index & 1) === 0 ? "" + y + "" : " " + y + " ")) + .join("") + "
    " + x[1] + "
    ").join(""); + const div_shortcuts = document.createElement("div"); + addClass(div_shortcuts, "shortcuts"); + div_shortcuts.innerHTML = "

    Keyboard Shortcuts

    " + shortcuts + "
    "; + + const infos = [ + "Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.", + "Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.", + "Search functions by type signature (e.g., vec -> usize or \ + -> vec)", + "Search multiple things at once by splitting your query with comma (e.g., \ + str,u8 or String,struct:Vec,test)", + "You can look for items with an exact name by putting double quotes around \ + your request: \"string\"", + "Look for items inside another one by searching for a path: vec::Vec", + ].map(x => "

    " + x + "

    ").join(""); + const div_infos = document.createElement("div"); + addClass(div_infos, "infos"); + div_infos.innerHTML = "

    Search Tricks

    " + infos; + + const rustdoc_version = document.createElement("span"); + rustdoc_version.className = "bottom"; + const rustdoc_version_code = document.createElement("code"); + rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version"); + rustdoc_version.appendChild(rustdoc_version_code); + + const container = document.createElement("div"); + if (!isHelpPage) { + container.className = "popover"; + } + container.id = "help"; + container.style.display = "none"; + + const side_by_side = document.createElement("div"); + side_by_side.className = "side-by-side"; + side_by_side.appendChild(div_shortcuts); + side_by_side.appendChild(div_infos); + + container.appendChild(book_info); + container.appendChild(side_by_side); + container.appendChild(rustdoc_version); + + if (isHelpPage) { + const help_section = document.createElement("section"); + help_section.appendChild(container); + document.getElementById("main-content").appendChild(help_section); + container.style.display = "block"; + } else { + const help_button = getHelpButton(); + help_button.appendChild(container); + + container.onblur = helpBlurHandler; + container.onclick = event => { + event.preventDefault(); + }; + help_button.onblur = helpBlurHandler; + help_button.children[0].onblur = helpBlurHandler; + } + + return container; + } + + /** + * Hide all the popover menus. + */ + window.hidePopoverMenus = function() { + onEachLazy(document.querySelectorAll(".search-form .popover"), elem => { + elem.style.display = "none"; + }); + }; + + /** + * Returns the help menu element (not the button). + * + * @param {boolean} buildNeeded - If this argument is `false`, the help menu element won't be + * built if it doesn't exist. + * + * @return {HTMLElement} + */ + function getHelpMenu(buildNeeded) { + let menu = getHelpButton().querySelector(".popover"); + if (!menu && buildNeeded) { + menu = buildHelpMenu(); + } + return menu; + } + + /** + * Show the help popup menu. + */ + function showHelp() { + const menu = getHelpMenu(true); + if (menu.style.display === "none") { + window.hidePopoverMenus(); + menu.style.display = ""; + } + } + + if (isHelpPage) { + showHelp(); + document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { + // Already on the help page, make help button a no-op. + const target = event.target; + if (target.tagName !== "A" || + target.parentElement.id !== HELP_BUTTON_ID || + event.ctrlKey || + event.altKey || + event.metaKey) { + return; + } + event.preventDefault(); + }); + } else { + document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { + // By default, have help button open docs in a popover. + // If user clicks with a moderator, though, use default browser behavior, + // probably opening in a new window or tab. + const target = event.target; + if (target.tagName !== "A" || + target.parentElement.id !== HELP_BUTTON_ID || + event.ctrlKey || + event.altKey || + event.metaKey) { + return; + } + event.preventDefault(); + const menu = getHelpMenu(true); + const shouldShowHelp = menu.style.display === "none"; + if (shouldShowHelp) { + showHelp(); + } else { + window.hidePopoverMenus(); + } + }); + } + + setMobileTopbar(); + addSidebarItems(); + addSidebarCrates(); + onHashChange(null); + window.addEventListener("hashchange", onHashChange); + searchState.setup(); +}()); + +(function() { + let reset_button_timeout = null; + + window.copy_path = but => { + const parent = but.parentElement; + const path = []; + + onEach(parent.childNodes, child => { + if (child.tagName === "A") { + path.push(child.textContent); + } + }); + + const el = document.createElement("textarea"); + el.value = path.join("::"); + el.setAttribute("readonly", ""); + // To not make it appear on the screen. + el.style.position = "absolute"; + el.style.left = "-9999px"; + + document.body.appendChild(el); + el.select(); + document.execCommand("copy"); + document.body.removeChild(el); + + // There is always one children, but multiple childNodes. + but.children[0].style.display = "none"; + + let tmp; + if (but.childNodes.length < 2) { + tmp = document.createTextNode("✓"); + but.appendChild(tmp); + } else { + onEachLazy(but.childNodes, e => { + if (e.nodeType === Node.TEXT_NODE) { + tmp = e; + return true; + } + }); + tmp.textContent = "✓"; + } + + if (reset_button_timeout !== null) { + window.clearTimeout(reset_button_timeout); + } + + function reset_button() { + tmp.textContent = ""; + reset_button_timeout = null; + but.children[0].style.display = ""; + } + + reset_button_timeout = window.setTimeout(reset_button, 1000); + }; +}()); diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 000000000..fdb8a8c65 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ +/* ignore-tidy-linelength */ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} diff --git a/static.files/noscript-13285aec31fa243e.css b/static.files/noscript-13285aec31fa243e.css new file mode 100644 index 000000000..54e8b6561 --- /dev/null +++ b/static.files/noscript-13285aec31fa243e.css @@ -0,0 +1,30 @@ +/* +This whole CSS file is used only in case rustdoc is rendered with javascript disabled. Since a lot +of content is hidden by default (depending on the settings too), we have to overwrite some of the +rules. +*/ + +#main-content .attributes { + /* Since there is no toggle (the "[-]") when JS is disabled, no need for this margin either. */ + margin-left: 0 !important; +} + +#copy-path { + /* It requires JS to work so no need to display it in this case. */ + display: none; +} + +nav.sub { + /* The search bar and related controls don't work without JS */ + display: none; +} + +.source .sidebar { + display: none; +} + +.notable-traits { + /* layout requires javascript + https://github.com/rust-lang/rust/issues/102576 */ + display: none; +} diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 000000000..62424d8ff --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-eabf764633b9d7be.css b/static.files/rustdoc-eabf764633b9d7be.css new file mode 100644 index 000000000..6a068a3d2 --- /dev/null +++ b/static.files/rustdoc-eabf764633b9d7be.css @@ -0,0 +1,2123 @@ +/* See FiraSans-LICENSE.txt for the Fira Sans license. */ +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans'), + url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium'), + url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2"); + font-display: swap; +} + +/* See SourceSerif4-LICENSE.md for the Source Serif 4 license. */ +@font-face { + font-family: 'Source Serif 4'; + font-style: normal; + font-weight: 400; + src: local('Source Serif 4'), + url("SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Source Serif 4'; + font-style: italic; + font-weight: 400; + src: local('Source Serif 4 Italic'), + url("SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Source Serif 4'; + font-style: normal; + font-weight: 700; + src: local('Source Serif 4 Bold'), + url("SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2") format("woff2"); + font-display: swap; +} + +/* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + /* Avoid using locally installed font because bad versions are in circulation: + * see https://github.com/rust-lang/rust/issues/24355 */ + src: url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Source Code Pro'; + font-style: italic; + font-weight: 400; + src: url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2"); + font-display: swap; +} +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 600; + src: url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2"); + font-display: swap; +} + +/* Avoid using legacy CJK serif fonts in Windows like Batang. */ +@font-face { + font-family: 'NanumBarunGothic'; + src: url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2"); + font-display: swap; + unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF; +} + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +/* This part handles the "default" theme being used depending on the system one. */ +html { + content: ""; +} +@media (prefers-color-scheme: light) { + html { + content: "light"; + } +} +@media (prefers-color-scheme: dark) { + html { + content: "dark"; + } +} + +/* General structure and fonts */ + +body { + /* Line spacing at least 1.5 per Web Content Accessibility Guidelines + https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ + font: 1rem/1.5 "Source Serif 4", NanumBarunGothic, serif; + margin: 0; + position: relative; + /* We use overflow-wrap: break-word for Safari, which doesn't recognize + `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */ + overflow-wrap: break-word; + /* Then override it with `anywhere`, which is required to make non-Safari browsers break + more aggressively when we want them to. */ + overflow-wrap: anywhere; + + -webkit-font-feature-settings: "kern", "liga"; + -moz-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; + + background-color: var(--main-background-color); + color: var(--main-color); +} + +h1 { + font-size: 1.5rem; /* 24px */ +} +h2 { + font-size: 1.375rem; /* 22px */ +} +h3 { + font-size: 1.25rem; /* 20px */ +} +h1, h2, h3, h4, h5, h6 { + font-weight: 500; +} +h1, h2, h3, h4 { + margin: 25px 0 15px 0; + padding-bottom: 6px; +} +.docblock h3, .docblock h4, h5, h6 { + margin: 15px 0 5px 0; +} +.docblock > h2:first-child, +.docblock > h3:first-child, +.docblock > h4:first-child, +.docblock > h5:first-child, +.docblock > h6:first-child { + margin-top: 0; +} +h1.fqn { + margin: 0; + padding: 0; + flex-grow: 1; + /* We use overflow-wrap: break-word for Safari, which doesn't recognize + `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */ + overflow-wrap: break-word; + /* Then override it with `anywhere`, which is required to make non-Safari browsers break + more aggressively when we want them to. */ + overflow-wrap: anywhere; +} +.main-heading { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding-bottom: 6px; + margin-bottom: 15px; +} +/* The only headings that get underlines are: + Markdown-generated headings within the top-doc + Rustdoc-generated h2 section headings (e.g. "Implementations", "Required Methods", etc) + Underlines elsewhere in the documentation break up visual flow and tend to invert + section hierarchies. */ +.content h2, +.top-doc .docblock > h3, +.top-doc .docblock > h4 { + border-bottom: 1px solid var(--headings-border-bottom-color); +} +h3.code-header { + font-size: 1.125rem; /* 18px */ +} +h4.code-header { + font-size: 1rem; +} +.code-header { + font-weight: 600; + margin: 0; + padding: 0; + /* position notable traits in mobile mode within the header */ + position: relative; +} + +#crate-search, +h1, h2, h3, h4, h5, h6, +.sidebar, +.mobile-topbar, +.search-input, +.search-results .result-name, +.item-left > a, +.out-of-band, +span.since, +a.srclink, +#help-button > a, +details.rustdoc-toggle.top-doc > summary, +details.rustdoc-toggle.non-exhaustive > summary, +.scraped-example-title, +.more-examples-toggle summary, .more-examples-toggle .hide-more, +.example-links a, +/* This selector is for the items listed in the "all items" page. */ +ul.all-items { + font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif; +} + +#toggle-all-docs, +a.anchor, +.small-section-header a, +#source-sidebar a, +pre.rust a, +.sidebar h2 a, +.sidebar h3 a, +.mobile-topbar h2 a, +h1 a, +.search-results a, +.module-item .stab, +.import-item .stab, +.result-name .primitive > i, .result-name .keyword > i, +.method .where, +.fn .where, +.where.fmt-newline { + color: var(--main-color); +} + +.content span.enum, .content a.enum, +.content span.struct, .content a.struct, +.content span.union, .content a.union, +.content span.primitive, .content a.primitive, +.content span.type, .content a.type, +.content span.foreigntype, .content a.foreigntype { + color: var(--type-link-color); +} + +.content span.trait, .content a.trait, +.content span.traitalias, .content a.traitalias { + color: var(--trait-link-color); +} + +.content span.associatedtype, .content a.associatedtype, +.content span.constant, .content a.constant, +.content span.static, .content a.static { + color: var(--assoc-item-link-color); +} + +.content span.fn, .content a.fn, +.content .fnname, +.content span.method, .content a.method, +.content span.tymethod, .content a.tymethod { + color: var(--function-link-color); +} + +.content span.attr, .content a.attr, +.content span.derive, .content a.derive, +.content span.macro, .content a.macro { + color: var(--macro-link-color); +} + +.content span.mod, .content a.mod { + color: var(--mod-link-color); +} + +.content span.keyword, .content a.keyword { + color: var(--keyword-link-color); +} + +a { + color: var(--link-color); +} + +ol, ul { + padding-left: 24px; +} +ul ul, ol ul, ul ol, ol ol { + margin-bottom: .625em; +} + +p { + /* Paragraph spacing at least 1.5 times line spacing per Web Content Accessibility Guidelines. + Line-height is 1.5rem, so line spacing is .5rem; .75em is 1.5 times that. + https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html */ + margin: 0 0 .75em 0; +} +/* For the last child of a div, the margin will be taken care of + by the margin-top of the next item. */ +p:last-child { + margin: 0; +} + +/* Fix some style changes due to normalize.css 8 */ + +button { + /* Buttons on Safari have different default padding than other platforms. Make them the same. */ + padding: 1px 6px; +} + +button#toggle-all-docs { + padding: 0; + background: none; + border: none; + cursor: pointer; + /* iOS button gradient: https://stackoverflow.com/q/5438567 */ + -webkit-appearance: none; + opacity: 1; +} + +/* end tweaks for normalize.css 8 */ + +.rustdoc { + display: flex; + flex-direction: row; + flex-wrap: nowrap; +} + +main { + position: relative; + flex-grow: 1; + padding: 10px 15px 40px 45px; + min-width: 0; +} + +.source main { + padding: 15px; +} + +.width-limiter { + max-width: 960px; + margin-right: auto; +} + +.source .width-limiter { + max-width: unset; +} + +details:not(.rustdoc-toggle) summary { + margin-bottom: .6em; +} + +code, pre, a.test-arrow, .code-header { + font-family: "Source Code Pro", monospace; +} +.docblock code, .docblock-short code { + border-radius: 3px; + padding: 0 0.125em; +} +.docblock pre code, .docblock-short pre code { + padding: 0; +} +pre { + padding: 14px; +} +.item-decl pre { + overflow-x: auto; +} + +.source .content pre { + padding: 20px; +} + +img { + max-width: 100%; +} + +.source .content { + overflow: visible; +} + +.sub-logo-container, .logo-container { + /* zero text boxes so that computed line height = image height exactly */ + line-height: 0; +} + +.sub-logo-container > img { + height: 60px; + width: 60px; + object-fit: contain; +} + +.rust-logo { + filter: var(--rust-logo-filter); +} + +.sidebar, .mobile-topbar, .sidebar-menu-toggle { + background-color: var(--sidebar-background-color); +} + +.sidebar { + font-size: 0.875rem; + width: 200px; + min-width: 200px; + overflow-y: scroll; + position: sticky; + height: 100vh; + top: 0; + left: 0; +} + +.rustdoc.source .sidebar { + width: 50px; + min-width: 0px; + max-width: 300px; + flex-grow: 0; + flex-shrink: 0; + flex-basis: auto; + border-right: 1px solid; + overflow-x: hidden; + /* The sidebar is by default hidden */ + overflow-y: hidden; +} + +.source .sidebar, #sidebar-toggle, #source-sidebar { + background-color: var(--sidebar-background-color); +} + +#sidebar-toggle > button:hover, #sidebar-toggle > button:focus { + background-color: var(--sidebar-background-color-hover); +} + +.source .sidebar > *:not(#sidebar-toggle) { + visibility: hidden; +} + +.source-sidebar-expanded .source .sidebar { + overflow-y: auto; + width: 300px; +} + +.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) { + visibility: visible; +} + +#all-types { + margin-top: 1em; +} + +/* Improve the scrollbar display on firefox */ +* { + scrollbar-width: initial; + scrollbar-color: var(--scrollbar-color); +} +.sidebar { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-color); +} + +/* Improve the scrollbar display on webkit-based browsers */ +::-webkit-scrollbar { + width: 12px; +} +.sidebar::-webkit-scrollbar { + width: 8px; +} +::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0; + background-color: var(--scrollbar-track-background-color); +} +.sidebar::-webkit-scrollbar-track { + background-color: var(--scrollbar-track-background-color); +} +::-webkit-scrollbar-thumb, .sidebar::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-thumb-background-color); +} + +/* Everything else */ + +.hidden { + display: none !important; +} + +.sidebar .logo-container { + margin-top: 10px; + margin-bottom: 10px; + text-align: center; +} + +.version { + overflow-wrap: break-word; +} + +.logo-container > img { + height: 100px; + width: 100px; +} + +ul.block, .block li { + padding: 0; + margin: 0; + list-style: none; +} + +.block a, +.sidebar h2 a, +.sidebar h3 a { + display: block; + padding: 0.25rem; + margin-left: -0.25rem; + + text-overflow: ellipsis; + overflow: hidden; +} + +.sidebar h2 { + overflow-wrap: anywhere; + padding: 0; + margin: 0.7rem 0; +} + +.sidebar h3 { + font-size: 1.125rem; /* 18px */ + padding: 0; + margin: 0; +} + +.sidebar-elems, +.sidebar > h2 { + padding-left: 24px; +} + +.sidebar a, .sidebar .current { + color: var(--sidebar-link-color); +} +.sidebar .current, +.sidebar a:hover { + background-color: var(--sidebar-current-link-background-color); +} + +.sidebar-elems .block { + margin-bottom: 2em; +} + +.sidebar-elems .block li a { + white-space: nowrap; +} + +.mobile-topbar { + display: none; +} + +.source .content pre.rust { + overflow: auto; + padding-left: 0; +} + +.rustdoc .example-wrap { + display: flex; + position: relative; + margin-bottom: 10px; +} +/* For the last child of a div, the margin will be taken care of + by the margin-top of the next item. */ +.rustdoc .example-wrap:last-child { + margin-bottom: 0px; +} + +.rustdoc .example-wrap > pre { + margin: 0; + flex-grow: 1; + overflow-x: auto; +} + +.rustdoc .example-wrap > pre.example-line-numbers, +.rustdoc .example-wrap > pre.src-line-numbers { + flex-grow: 0; + overflow: initial; + text-align: right; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.example-line-numbers { + border: 1px solid; + padding: 13px 8px; + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + border-color: var(--example-line-numbers-border-color); +} + +.src-line-numbers span { + cursor: pointer; + color: var(--src-line-numbers-span-color); +} +.src-line-numbers .line-highlighted { + background-color: var(--src-line-number-highlighted-background-color); +} +.src-line-numbers :target { + background-color: transparent; +} + +.search-loading { + text-align: center; +} + +.docblock-short { + overflow-wrap: break-word; + overflow-wrap: anywhere; + overflow: hidden; + text-overflow: ellipsis; +} +/* Wrap non-pre code blocks (`text`) but not (```text```). */ +.docblock > :not(pre) > code, +.docblock-short > code { + white-space: pre-wrap; +} + +.top-doc .docblock h2 { font-size: 1.375rem; } +.top-doc .docblock h3 { font-size: 1.25rem; } +.top-doc .docblock h4, +.top-doc .docblock h5 { + font-size: 1.125rem; +} +.top-doc .docblock h6 { + font-size: 1rem; +} + +.docblock h5 { font-size: 1rem; } +.docblock h6 { font-size: 0.875rem; } + +.docblock { + margin-left: 24px; + position: relative; +} + +.docblock > :not(.more-examples-toggle):not(.example-wrap) { + max-width: 100%; + overflow-x: auto; +} + +.out-of-band { + flex-grow: 0; + font-size: 1.125rem; +} + +.docblock code, .docblock-short code, +pre, .rustdoc.source .example-wrap { + background-color: var(--code-block-background-color); +} + +#main-content { + position: relative; +} + +.docblock table { + margin: .5em 0; + width: calc(100% - 2px); + overflow-x: auto; + display: block; + border-collapse: collapse; +} + +.docblock table td { + padding: .5em; + border: 1px dashed var(--border-color); + vertical-align: top; +} + +.docblock table th { + padding: .5em; + text-align: left; + border: 1px solid var(--border-color); +} + +/* Shift "where ..." part of method or fn definition down a line */ +.method .where, +.fn .where, +.where.fmt-newline { + display: block; + font-size: 0.875rem; +} + +.item-info { + display: block; + margin-left: 24px; +} + +.item-info code { + font-size: 0.875rem; +} + +#main-content > .item-info { + margin-left: 0; +} + +nav.sub { + flex-grow: 1; + flex-flow: row nowrap; + margin: 4px 0 25px 0; + display: flex; + align-items: center; +} +.search-form { + position: relative; + display: flex; + height: 34px; + flex-grow: 1; +} +.source nav.sub { + margin: 0 0 15px 0; +} +.source .search-form { + margin-left: 32px; +} + +a { + text-decoration: none; +} + +.small-section-header { + display: flex; + justify-content: space-between; + position: relative; +} + +.small-section-header:hover > .anchor { + display: initial; +} + +.impl:hover > .anchor, .trait-impl:hover > .anchor { + display: inline-block; + position: absolute; +} +.anchor { + display: none; + position: absolute; + left: -0.5em; + background: none !important; +} +.anchor.field { + left: -5px; +} +.small-section-header > .anchor { + left: -15px; + padding-right: 8px; +} +h2.small-section-header > .anchor { + padding-right: 6px; +} +.anchor::before { + content: '§'; +} + +.main-heading a:hover, +.example-wrap > pre.rust a:hover, +.all-items a:hover, +.docblock a:not(.test-arrow):not(.scrape-help):hover, +.docblock-short a:not(.test-arrow):not(.scrape-help):hover, +.item-info a { + text-decoration: underline; +} + +.crate.block a.current { font-weight: 500; } + +/* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap + as much as needed on mobile (see + src/test/rustdoc-gui/type-declaration-overflow.goml for an example of why + this matters). The `anywhere` value means: + + "Soft wrap opportunities introduced by the word break are considered when + calculating min-content intrinsic sizes." + + https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap#values + + For table layouts, that becomes a problem: the browser tries to make each + column as narrow as possible, and `overflow-wrap: anywhere` means it can do + so by breaking words - even if some other column could be shrunk without + breaking words! This shows up, for instance, in the `Structs` / `Modules` / + `Functions` (etcetera) sections of a module page, and when a docblock + contains a table. + + So, for table layouts, override the default with break-word, which does + _not_ affect min-content intrinsic sizes. +*/ +table, +.item-table { + overflow-wrap: break-word; +} + +.item-table { + display: table; +} +.item-row { + display: table-row; +} +.item-left, .item-right { + display: table-cell; +} +.item-left { + padding-right: 1.25rem; +} + +.search-results-title { + margin-top: 0; + white-space: nowrap; + /* flex layout allows shrinking the -element "#crate-search") to be shrunk */ + min-width: 5em; +} +#crate-search { + min-width: 115px; + /* keep these two in sync with "@-moz-document url-prefix()" below */ + padding: 0 23px 0 4px; + /* prevents the s */ +@-moz-document url-prefix() { + #crate-search { + padding-left: 0px; /* == 4px - 4px */ + padding-right: 19px; /* == 23px - 4px */ + } +} +/* pseudo-element for holding the dropdown-arrow image; needs to be a separate thing +so that we can apply CSS-filters to change the arrow color in themes */ +#crate-search-div::after { + /* lets clicks through! */ + pointer-events: none; + /* completely covers the underlying div */ + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + content: ""; + background-repeat: no-repeat; + background-size: 20px; + background-position: calc(100% - 2px) 56%; + /* image is black color */ + background-image: url("down-arrow-927217e04c7463ac.svg"); + /* changes the arrow image color */ + filter: var(--crate-search-div-filter); +} +#crate-search-div:hover::after, #crate-search-div:focus-within::after { + filter: var(--crate-search-div-hover-filter); +} +#crate-search > option { + font-size: 1rem; +} +.search-input { + /* Override Normalize.css: it has a rule that sets + -webkit-appearance: textfield for search inputs. That + causes rounded corners and no border on iOS Safari. */ + -webkit-appearance: none; + outline: none; + border: 1px solid var(--border-color); + border-radius: 2px; + padding: 8px; + font-size: 1rem; + flex-grow: 1; + background-color: var(--button-background-color); + color: var(--search-color); +} +.search-input:focus { + border-color: var(--search-input-focused-border-color); +} + +.search-results { + display: none; +} + +.search-results.active { + display: block; +} + +.search-results > a { + display: flex; + /* A little margin ensures the browser's outlining of focused links has room to display. */ + margin-left: 2px; + margin-right: 2px; + border-bottom: 1px solid var(--search-result-border-color); + gap: 1em; +} + +.search-results > a > div { + flex: 1; +} + +.search-results > a > div.desc { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; +} + +.search-results a:hover, +.search-results a:focus { + background-color: var(--search-result-link-focus-background-color); +} + +.popover { + font-size: 1rem; + position: absolute; + right: 0; + z-index: 2; + display: block; + margin-top: 7px; + border-radius: 3px; + border: 1px solid var(--border-color); + font-size: 1rem; +} + +/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ +.popover::before { + content: ''; + position: absolute; + right: 11px; + border: solid var(--border-color); + border-width: 1px 1px 0 0; + display: inline-block; + padding: 4px; + transform: rotate(-45deg); + top: -5px; +} + +.popover, .popover::before { + background-color: var(--main-background-color); + color: var(--main-color); +} + +/* use larger max-width for help popover, but not for help.html */ +#help.popover { + max-width: 600px; +} + +#help.popover::before { + right: 48px; +} + +#help dt { + float: left; + clear: left; + display: block; + margin-right: 0.5rem; +} +#help span.top, #help span.bottom { + text-align: center; + display: block; + font-size: 1.125rem; +} +#help span.top { + margin: 10px 0; + border-bottom: 1px solid var(--border-color); + padding-bottom: 4px; + margin-bottom: 6px; +} +#help span.bottom { + clear: both; + border-top: 1px solid var(--border-color); +} +.side-by-side > div { + width: 50%; + float: left; + padding: 0 20px 20px 17px; +} + +.item-info .stab { + width: fit-content; + /* This min-height is needed to unify the height of the stab elements because some of them + have emojis. + */ + min-height: 36px; + display: flex; + align-items: center; + white-space: pre-wrap; +} +.stab { + padding: 3px; + margin-bottom: 5px; + font-size: 0.875rem; + font-weight: normal; + color: var(--main-color); + background-color: var(--stab-background-color); +} + +.stab.portability > code { + background: none; + color: var(--stab-code-color); +} + +.stab .emoji { + font-size: 1.25rem; + margin-right: 0.3rem; +} + +/* This is to prevent the `.stab` elements to overflow the .docblock elements. */ +.docblock .stab { + padding: 0 0.125em; + margin-bottom: 0; +} + +/* Black one-pixel outline around emoji shapes */ +.emoji { + text-shadow: + 1px 0 0 black, + -1px 0 0 black, + 0 1px 0 black, + 0 -1px 0 black; +} + +.module-item .stab, +.import-item .stab { + border-radius: 3px; + display: inline-block; + font-size: 0.875rem; + line-height: 1.2; + margin-bottom: 0; + margin-left: 0.3125em; + padding: 2px; + vertical-align: text-bottom; +} + +.module-item.unstable, +.import-item.unstable { + opacity: 0.65; +} + +.since { + font-weight: normal; + font-size: initial; +} + +.rightside { + padding-left: 12px; + padding-right: 2px; + float: right; +} + +.rightside:not(a), +.out-of-band { + color: var(--right-side-color); +} + +pre.rust { + tab-size: 4; + -moz-tab-size: 4; +} + +/* Code highlighting */ +pre.rust .kw { + color: var(--code-highlight-kw-color); +} +pre.rust .kw-2 { + color: var(--code-highlight-kw-2-color); +} +pre.rust .lifetime { + color: var(--code-highlight-lifetime-color); +} +pre.rust .prelude-ty { + color: var(--code-highlight-prelude-color); +} +pre.rust .prelude-val { + color: var(--code-highlight-prelude-val-color); +} +pre.rust .string { + color: var(--code-highlight-string-color); +} +pre.rust .number { + color: var(--code-highlight-number-color); +} +pre.rust .bool-val { + color: var(--code-highlight-literal-color); +} +pre.rust .self { + color: var(--code-highlight-self-color); +} +pre.rust .attr { + color: var(--code-highlight-attribute-color); +} +pre.rust .macro, +pre.rust .macro-nonterminal { + color: var(--code-highlight-macro-color); +} +pre.rust .question-mark { + font-weight: bold; + color: var(--code-highlight-question-mark-color); +} +pre.rust .comment { + color: var(--code-highlight-comment-color); +} +pre.rust .doccomment { + color: var(--code-highlight-doc-comment-color); +} + +.example-wrap.compile_fail, +.example-wrap.should_panic { + border-left: 2px solid var(--codeblock-error-color); +} + +.ignore.example-wrap { + border-left: 2px solid var(--codeblock-ignore-color); +} + +.example-wrap.compile_fail:hover, +.example-wrap.should_panic:hover { + border-left: 2px solid var(--codeblock-error-hover-color); +} + +.example-wrap.ignore:hover { + border-left: 2px solid var(--codeblock-ignore-hover-color); +} + +.example-wrap.compile_fail .tooltip, +.example-wrap.should_panic .tooltip { + color: var(--codeblock-error-color); +} + +.example-wrap.ignore .tooltip { + color: var(--codeblock-ignore-color); +} + +.example-wrap.compile_fail:hover .tooltip, +.example-wrap.should_panic:hover .tooltip { + color: var(--codeblock-error-hover-color); +} + +.example-wrap.ignore:hover .tooltip { + color: var(--codeblock-ignore-hover-color); +} + +.example-wrap .tooltip { + position: absolute; + display: block; + cursor: pointer; + left: -25px; + top: 5px; +} + +.example-wrap .tooltip::after { + display: none; + text-align: center; + padding: 5px 3px 3px 3px; + border-radius: 6px; + margin-left: 5px; + font-size: 1rem; + border: 1px solid var(--border-color); + position: absolute; + width: max-content; + top: -2px; + z-index: 1; +} + +.example-wrap .tooltip::before { + content: " "; + position: absolute; + top: 50%; + left: 16px; + margin-top: -5px; + border-width: 5px; + border-style: solid; + display: none; + z-index: 1; +} + +.example-wrap.ignore .tooltip::after { + content: "This example is not tested"; +} +.example-wrap.compile_fail .tooltip::after { + content: "This example deliberately fails to compile"; +} +.example-wrap.should_panic .tooltip::after { + content: "This example panics"; +} +.example-wrap.edition .tooltip::after { + content: "This code runs with edition " attr(data-edition); +} + +.example-wrap .tooltip:hover::before, .example-wrap .tooltip:hover::after { + display: inline; +} + +.example-wrap.compile_fail .tooltip, +.example-wrap.should_panic .tooltip, +.example-wrap.ignore .tooltip { + font-weight: bold; + font-size: 1.25rem; +} + +a.test-arrow { + display: inline-block; + visibility: hidden; + position: absolute; + padding: 5px 10px 5px 10px; + border-radius: 5px; + font-size: 1.375rem; + top: 5px; + right: 5px; + z-index: 1; + color: var(--test-arrow-color); + background-color: var(--test-arrow-background-color); +} +a.test-arrow:hover { + color: var(--test-arrow-hover-color); + background-color: var(--test-arrow-hover-background-color); +} +.example-wrap:hover .test-arrow { + visibility: visible; +} + +.code-attribute { + font-weight: 300; + color: var(--code-attribute-color); +} + +.item-spacer { + width: 100%; + height: 12px; +} + +.out-of-band > span.since { + font-size: 1.25rem; +} + +h3.variant { + font-weight: 600; + font-size: 1.125rem; + margin-bottom: 10px; +} + +.sub-variant h4 { + font-size: 1rem; + font-weight: 400; + margin-top: 0; + margin-bottom: 0; +} + +.sub-variant { + margin-left: 24px; + margin-bottom: 40px; +} + +.sub-variant > .sub-variant-field { + margin-left: 24px; +} + +:target > code, :target > .code-header { + opacity: 1; +} + +:target { + padding-right: 3px; + background-color: var(--target-background-color); + border-right: 3px solid var(--target-border-color); +} + +.notable-traits-tooltip { + display: inline-block; + cursor: pointer; +} + +.notable-traits .notable-traits-tooltiptext { + display: inline-block; + visibility: hidden; +} + +.notable-traits-tooltiptext { + padding: 5px 3px 3px 3px; + border-radius: 6px; + margin-left: 5px; + z-index: 10; + font-size: 1rem; + cursor: default; + position: absolute; + border: 1px solid; +} + +.notable-traits-tooltip::after { + /* The margin on the tooltip does not capture hover events, + this extends the area of hover enough so that mouse hover is not + lost when moving the mouse to the tooltip */ + content: "\00a0\00a0\00a0"; +} + +.notable-traits-tooltiptext .docblock { + margin: 0; +} + +.notable-traits-tooltiptext .notable { + font-size: 1.1875rem; + font-weight: 600; + display: block; +} + +.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code { + background: transparent; +} + +.notable-traits-tooltiptext .docblock pre.content { + margin: 0; + padding: 0; + font-size: 1.25rem; + white-space: pre-wrap; + overflow: hidden; +} + +.search-failed { + text-align: center; + margin-top: 20px; + display: none; +} + +.search-failed.active { + display: block; +} + +.search-failed > ul { + text-align: left; + max-width: 570px; + margin-left: auto; + margin-right: auto; +} + +#titles { + display: flex; + flex-direction: row; + gap: 1px; + margin-bottom: 4px; +} + +#titles > button { + text-align: center; + font-size: 1.125rem; + cursor: pointer; + border: 0; + border-top: 2px solid; + flex: 1; + line-height: 1.5; + color: inherit; +} + +#titles > button > div.count { + display: inline-block; + font-size: 1rem; +} + +.notable-traits { + cursor: pointer; + z-index: 2; + margin-left: 5px; +} + +#sidebar-toggle { + position: sticky; + top: 0; + left: 0; + font-size: 1.25rem; + border-bottom: 1px solid; + display: flex; + height: 40px; + justify-content: center; + align-items: center; + z-index: 10; +} +#source-sidebar { + width: 100%; + overflow: auto; +} +#source-sidebar > .title { + font-size: 1.5rem; + text-align: center; + border-bottom: 1px solid var(--border-color); + margin-bottom: 6px; +} +#sidebar-toggle > button { + font-size: inherit; + font-weight: bold; + background: none; + color: inherit; + cursor: pointer; + text-align: center; + border: none; + outline: none; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + /* work around button layout strangeness: https://stackoverflow.com/q/7271561 */ + width: 100%; + /* iOS button gradient: https://stackoverflow.com/q/5438567 */ + -webkit-appearance: none; + opacity: 1; +} +#settings-menu, #help-button { + margin-left: 4px; + outline: none; +} + +#settings-menu > a, #help-button > a, #copy-path { + width: 33px; + cursor: pointer; + line-height: 1.5; +} + +#settings-menu > a, #help-button > a { + padding: 5px; + height: 100%; + display: block; + background-color: var(--button-background-color); + border: 1px solid var(--border-color); + border-radius: 2px; +} + +#copy-path { + color: var(--copy-path-button-color); + background: var(--main-background-color); + height: 34px; + margin-left: 10px; + padding: 0; + padding-left: 2px; + border: 0; +} +#copy-path > img { + filter: var(--copy-path-img-filter); +} +#copy-path:hover > img { + filter: var(--copy-path-img-hover-filter); +} + +@keyframes rotating { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +#settings-menu.rotate > a img { + animation: rotating 2s linear infinite; +} + +#help-button > a { + text-align: center; + /* Rare exception to specifying font sizes in rem. Since this is acting + as an icon, it's okay to specify their sizes in pixels. */ + font-size: 20px; + padding-top: 2px; +} + +kbd { + display: inline-block; + padding: 3px 5px; + font: 15px monospace; + line-height: 10px; + vertical-align: middle; + border: solid 1px var(--border-color); + border-radius: 3px; + cursor: default; +} + +ul.all-items > li { + list-style: none; +} + +details.dir-entry { + padding-left: 4px; +} + +details.dir-entry > summary::after { + content: " ►"; + position: absolute; + left: -15px; + top: 0px; + font-size: 80%; + padding: 2px 0px; + /* set width to cover gap between arrow and text */ + width: 25px; +} + +details[open].dir-entry > summary::after { + content: " ▼"; +} + +details.dir-entry > summary::-webkit-details-marker, +details.dir-entry > summary::marker { + display: none; +} + +details.dir-entry > summary { + margin: 0 0 0 13px; + list-style: none; + cursor: pointer; + position: relative; +} + +details.dir-entry div.folders, details.dir-entry div.files { + padding-left: 23px; +} + +details.dir-entry a { + display: block; +} + +/* We use CSS containment on the details elements because most sizeable elements + of the page are contained in one of these. This also makes re-rendering + faster on document changes (like closing and opening toggles). + Unfortunately we can't yet specify contain: content or contain: strict + because the [-]/[+] toggles extend past the boundaries of the
    + https://developer.mozilla.org/en-US/docs/Web/CSS/contain */ +details.rustdoc-toggle { + contain: layout; + position: relative; +} + +/* The hideme class is used on summary tags that contain a span with + placeholder text shown only when the toggle is closed. For instance, + "Expand description" or "Show methods". */ +details.rustdoc-toggle > summary.hideme { + cursor: pointer; +} + +details.rustdoc-toggle > summary { + list-style: none; + /* focus outline is shown on `::before` instead of this */ + outline: none; +} +details.rustdoc-toggle > summary::-webkit-details-marker, +details.rustdoc-toggle > summary::marker { + display: none; +} + +details.rustdoc-toggle > summary.hideme > span { + margin-left: 9px; +} + +details.rustdoc-toggle > summary::before { + content: ""; + cursor: pointer; + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: top left; + display: inline-block; + vertical-align: middle; + opacity: .5; +} + +details.rustdoc-toggle > summary.hideme > span, +.more-examples-toggle summary, .more-examples-toggle .hide-more { + color: var(--toggles-color); +} + +/* Screen readers see the text version at the end the line. + Visual readers see the icon at the start of the line, but small and transparent. */ +details.rustdoc-toggle > summary::after { + content: "Expand"; + overflow: hidden; + width: 0; + height: 0; + position: absolute; +} + +details.rustdoc-toggle > summary.hideme::after { + /* "hideme" toggles already have a description when they're contracted */ + content: ""; +} + +details.rustdoc-toggle > summary:focus::before, +details.rustdoc-toggle > summary:hover::before { + opacity: 1; +} + +details.rustdoc-toggle > summary:focus-visible::before { + /* The SVG is black, and gets turned white using a filter in the dark themes. + Do the same with the outline. + The dotted 1px style is copied from Firefox's focus ring style. + */ + outline: 1px dotted #000; + outline-offset: 1px; +} + +details.rustdoc-toggle.top-doc > summary, +details.rustdoc-toggle.top-doc > summary::before, +details.rustdoc-toggle.non-exhaustive > summary, +details.rustdoc-toggle.non-exhaustive > summary::before { + font-size: 1rem; +} + +details.non-exhaustive { + margin-bottom: 8px; +} + +details.rustdoc-toggle > summary.hideme::before { + position: relative; +} + +details.rustdoc-toggle > summary:not(.hideme)::before { + position: absolute; + left: -24px; + top: 4px; +} + +.impl-items > details.rustdoc-toggle > summary:not(.hideme)::before { + position: absolute; + left: -24px; +} + +/* When a "hideme" summary is open and the "Expand description" or "Show + methods" text is hidden, we want the [-] toggle that remains to not + affect the layout of the items to its right. To do that, we use + absolute positioning. Note that we also set position: relative + on the parent
    to make this work properly. */ +details.rustdoc-toggle[open] > summary.hideme { + position: absolute; +} + +details.rustdoc-toggle[open] > summary.hideme > span { + display: none; +} + +details.rustdoc-toggle[open] > summary::before, +details.rustdoc-toggle[open] > summary.hideme::before { + background-image: url("toggle-minus-31bbd6e4c77f5c96.svg"); +} + +details.rustdoc-toggle > summary::before { + background-image: url("toggle-plus-1092eb4930d581b0.svg"); +} + +details.rustdoc-toggle[open] > summary::before, +details.rustdoc-toggle[open] > summary.hideme::before { + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: top left; + display: inline-block; + content: ""; +} + +details.rustdoc-toggle[open] > summary::after, +details.rustdoc-toggle[open] > summary.hideme::after { + content: "Collapse"; +} + +/* This is needed in docblocks to have the "▶" element to be on the same line. */ +.docblock summary > * { + display: inline-block; +} + +/* In case there is no documentation before a code block, we need to add some margin at the top +to prevent an overlay between the "collapse toggle" and the information tooltip. +However, it's not needed with smaller screen width because the doc/code block is always put +"one line" below. */ +.docblock > .example-wrap:first-child .tooltip { + margin-top: 16px; +} + +/* Media Queries */ + +/* +WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY +If you update this line, then you also need to update the line with the same warning +in storage.js +*/ +@media (max-width: 700px) { + /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, + or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured + by the topbar. Anything with an `id` gets scroll-margin-top equal to .mobile-topbar's size. + */ + *[id] { + scroll-margin-top: 45px; + } + + .rustdoc { + /* Sidebar should overlay main content, rather than pushing main content to the right. + Turn off `display: flex` on the body element. */ + display: block; + } + + main { + padding-left: 15px; + padding-top: 0px; + } + + .main-heading { + flex-direction: column; + } + + .out-of-band { + text-align: left; + margin-left: initial; + padding: initial; + } + + .out-of-band .since::before { + content: "Since "; + } + + #copy-path { + display: none; + } + + /* Hide the logo and item name from the sidebar. Those are displayed + in the mobile-topbar instead. */ + .sidebar .sidebar-logo, + .sidebar .location { + display: none; + } + + .sidebar { + position: fixed; + top: 45px; + /* Hide the sidebar offscreen while not in use. Doing this instead of display: none means + the sidebar stays visible for screen readers, which is useful for navigation. */ + left: -1000px; + margin: 0; + padding: 0; + z-index: 11; + /* Reduce height slightly to account for mobile topbar. */ + height: calc(100vh - 45px); + } + + /* The source view uses a different design for the sidebar toggle, and doesn't have a topbar, + so don't bump down the main content or the sidebar. */ + .source main, + .rustdoc.source .sidebar { + top: 0; + padding: 0; + height: 100vh; + border: 0; + } + + .sidebar.shown, + .source-sidebar-expanded .source .sidebar, + .sidebar:focus-within { + left: 0; + } + + .rustdoc.source > .sidebar { + width: 0; + } + + .mobile-topbar h2 { + padding-bottom: 0; + margin: auto 0.5em auto auto; + overflow: hidden; + /* Rare exception to specifying font sizes in rem. Since the topbar + height is specified in pixels, this also has to be specified in + pixels to avoid overflowing the topbar when the user sets a bigger + font size. */ + font-size: 24px; + } + + .mobile-topbar h2 a { + display: block; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + + .mobile-topbar .logo-container > img { + max-width: 35px; + max-height: 35px; + margin: 5px 0 5px 20px; + } + + .mobile-topbar { + display: flex; + flex-direction: row; + position: sticky; + z-index: 10; + font-size: 2rem; + height: 45px; + width: 100%; + left: 0; + top: 0; + } + + .sidebar-menu-toggle { + width: 45px; + /* Rare exception to specifying font sizes in rem. Since this is acting + as an icon, it's okay to specify its sizes in pixels. */ + font-size: 32px; + border: none; + color: var(--main-color); + } + + .sidebar-elems { + margin-top: 1em; + } + + .content { + margin-left: 0px; + } + + .anchor { + display: none !important; + } + + #titles > button > div.count { + display: block; + } + + #main-content > details.rustdoc-toggle > summary::before, + #main-content > div > details.rustdoc-toggle > summary::before { + left: -11px; + } + + #sidebar-toggle { + position: fixed; + left: 1px; + top: 100px; + width: 30px; + font-size: 1.5rem; + text-align: center; + padding: 0; + z-index: 10; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + cursor: pointer; + border: 1px solid; + border-left: 0; + } + + .source-sidebar-expanded #sidebar-toggle { + left: unset; + top: unset; + width: unset; + border-top-right-radius: unset; + border-bottom-right-radius: unset; + position: sticky; + border: 0; + border-bottom: 1px solid; + } + + .notable-traits .notable-traits-tooltiptext { + left: 0; + top: 100%; + } + + /* We don't display the help button on mobile devices. */ + #help-button { + display: none; + } + + /* Display an alternating layout on tablets and phones */ + .item-table, .item-row, .item-left, .item-right, + .search-results > a, .search-results > a > div { + display: block; + } + + /* Display an alternating layout on tablets and phones */ + .search-results > a { + padding: 5px 0px; + } + .search-results > a > div.desc, .item-right { + padding-left: 2em; + } + + .source-sidebar-expanded .source .sidebar { + max-width: 100vw; + width: 100vw; + } + + /* Position of the "[-]" element. */ + details.rustdoc-toggle:not(.top-doc) > summary { + margin-left: 10px; + } + .impl-items > details.rustdoc-toggle > summary:not(.hideme)::before, + #main-content > details.rustdoc-toggle:not(.top-doc) > summary::before, + #main-content > div > details.rustdoc-toggle > summary::before { + left: -11px; + } + + /* Align summary-nested and unnested item-info gizmos. */ + .impl-items > .item-info { + margin-left: 34px; + } + + .source nav.sub { + margin: 0; + padding: 8px; + } +} + +@media print { + nav.sidebar, nav.sub, .out-of-band, a.srclink, #copy-path, + details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle > summary::before, + details.rustdoc-toggle.top-doc > summary { + display: none; + } + + .docblock { + margin-left: 0; + } + + main { + padding: 10px; + } +} + +@media (max-width: 464px) { + .docblock { + margin-left: 12px; + } + + .docblock code { + overflow-wrap: break-word; + overflow-wrap: anywhere; + } + + nav.sub { + flex-direction: column; + } + + .search-form { + align-self: stretch; + } + + .sub-logo-container > img { + height: 35px; + width: 35px; + } + + #sidebar-toggle { + top: 10px; + } + .source-sidebar-expanded #sidebar-toggle { + top: unset; + } +} + +.implementors-toggle > summary, +.impl, +#implementors-list > .docblock, +.impl-items > section, +.impl-items > .rustdoc-toggle > summary, +.methods > section, +.methods > .rustdoc-toggle > summary +{ + margin-bottom: 0.75em; +} + +.impl-items > .rustdoc-toggle[open]:not(:last-child), +.methods > .rustdoc-toggle[open]:not(:last-child), +.implementors-toggle[open]:not(:last-child) { + margin-bottom: 2em; +} + +#trait-implementations-list .impl-items > .rustdoc-toggle:not(:last-child), +#synthetic-implementations-list .impl-items > .rustdoc-toggle:not(:last-child), +#blanket-implementations-list .impl-items > .rustdoc-toggle:not(:last-child) { + margin-bottom: 1em; +} + +/* Begin: styles for --scrape-examples feature */ + +.scraped-example-list .scrape-help { + margin-left: 10px; + padding: 0 4px; + font-weight: normal; + font-size: 12px; + position: relative; + bottom: 1px; + background: transparent; + border-width: 1px; + border-style: solid; + border-radius: 50px; +} + +.scraped-example .code-wrapper { + position: relative; + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 100%; +} + +.scraped-example:not(.expanded) .code-wrapper { + max-height: 240px; +} + +.scraped-example:not(.expanded) .code-wrapper pre { + overflow-y: hidden; + max-height: 240px; + padding-bottom: 0; +} + +.scraped-example .code-wrapper .next, +.scraped-example .code-wrapper .prev, +.scraped-example .code-wrapper .expand { + position: absolute; + top: 0.25em; + z-index: 1; + cursor: pointer; +} +.scraped-example .code-wrapper .prev { + right: 2.25em; +} +.scraped-example .code-wrapper .next { + right: 1.25em; +} +.scraped-example .code-wrapper .expand { + right: 0.25em; +} + +.scraped-example:not(.expanded) .code-wrapper:before, +.scraped-example:not(.expanded) .code-wrapper:after { + content: " "; + width: 100%; + height: 5px; + position: absolute; + z-index: 1; +} +.scraped-example:not(.expanded) .code-wrapper:before { + top: 0; +} +.scraped-example:not(.expanded) .code-wrapper:after { + bottom: 0; +} + +.scraped-example .code-wrapper .src-line-numbers { + margin: 0; + padding: 14px 0; +} + +.scraped-example .code-wrapper .src-line-numbers span { + padding: 0 14px; +} + +.scraped-example .code-wrapper .example-wrap { + flex: 1; + overflow-x: auto; + overflow-y: hidden; + margin-bottom: 0; +} + +.scraped-example:not(.expanded) .code-wrapper .example-wrap { + overflow-x: hidden; +} + +.scraped-example .code-wrapper .example-wrap pre.rust { + overflow-x: inherit; + width: inherit; + overflow-y: hidden; +} + + +.more-examples-toggle { + max-width: calc(100% + 25px); + margin-top: 10px; + margin-left: -25px; +} + +.more-examples-toggle .hide-more { + margin-left: 25px; + margin-bottom: 5px; + cursor: pointer; +} + +.more-scraped-examples { + margin-left: 5px; + display: flex; + flex-direction: row; +} + +.more-scraped-examples-inner { + /* 20px is width of toggle-line + toggle-line-inner */ + width: calc(100% - 20px); +} + +.toggle-line { + align-self: stretch; + margin-right: 10px; + margin-top: 5px; + padding: 0 4px; + cursor: pointer; +} + +.toggle-line-inner { + min-width: 2px; + height: 100%; +} + +.more-scraped-examples .scraped-example { + margin-bottom: 20px; +} + +.more-scraped-examples .scraped-example:last-child { + margin-bottom: 0; +} + +.example-links a { + margin-top: 20px; +} + +.example-links ul { + margin-bottom: 0; +} + +/* End: styles for --scrape-examples feature */ diff --git a/static.files/scrape-examples-1f45318ad6bd2a81.js b/static.files/scrape-examples-1f45318ad6bd2a81.js new file mode 100644 index 000000000..d0fd115fd --- /dev/null +++ b/static.files/scrape-examples-1f45318ad6bd2a81.js @@ -0,0 +1,106 @@ +/* global addClass, hasClass, removeClass, onEachLazy */ + +"use strict"; + +(function() { + // Number of lines shown when code viewer is not expanded + const MAX_LINES = 10; + + // Scroll code block to the given code location + function scrollToLoc(elt, loc) { + const lines = elt.querySelector(".src-line-numbers"); + let scrollOffset; + + // If the block is greater than the size of the viewer, + // then scroll to the top of the block. Otherwise scroll + // to the middle of the block. + if (loc[1] - loc[0] > MAX_LINES) { + const line = Math.max(0, loc[0] - 1); + scrollOffset = lines.children[line].offsetTop; + } else { + const wrapper = elt.querySelector(".code-wrapper"); + const halfHeight = wrapper.offsetHeight / 2; + const offsetMid = (lines.children[loc[0]].offsetTop + + lines.children[loc[1]].offsetTop) / 2; + scrollOffset = offsetMid - halfHeight; + } + + lines.scrollTo(0, scrollOffset); + elt.querySelector(".rust").scrollTo(0, scrollOffset); + } + + function updateScrapedExample(example) { + const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent); + let locIndex = 0; + const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight")); + const link = example.querySelector(".scraped-example-title a"); + + if (locs.length > 1) { + // Toggle through list of examples in a given file + const onChangeLoc = changeIndex => { + removeClass(highlights[locIndex], "focus"); + changeIndex(); + scrollToLoc(example, locs[locIndex][0]); + addClass(highlights[locIndex], "focus"); + + const url = locs[locIndex][1]; + const title = locs[locIndex][2]; + + link.href = url; + link.innerHTML = title; + }; + + example.querySelector(".prev") + .addEventListener("click", () => { + onChangeLoc(() => { + locIndex = (locIndex - 1 + locs.length) % locs.length; + }); + }); + + example.querySelector("next") + .addEventListener("click", () => { + onChangeLoc(() => { + locIndex = (locIndex + 1) % locs.length; + }); + }); + } + + const expandButton = example.querySelector(".expand"); + if (expandButton) { + expandButton.addEventListener("click", () => { + if (hasClass(example, "expanded")) { + removeClass(example, "expanded"); + scrollToLoc(example, locs[0][0]); + } else { + addClass(example, "expanded"); + } + }); + } + + // Start with the first example in view + scrollToLoc(example, locs[0][0]); + } + + const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example"); + onEachLazy(firstExamples, updateScrapedExample); + onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => { + // Allow users to click the left border of the
    section to close it, + // since the section can be large and finding the [+] button is annoying. + onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"), button => { + button.addEventListener("click", () => { + toggle.open = false; + }); + }); + + const moreExamples = toggle.querySelectorAll(".scraped-example"); + toggle.querySelector("summary").addEventListener("click", () => { + // Wrapping in setTimeout ensures the update happens after the elements are actually + // visible. This is necessary since updateScrapedExample calls scrollToLoc which + // depends on offsetHeight, a property that requires an element to be visible to + // compute correctly. + setTimeout(() => { + onEachLazy(moreExamples, updateScrapedExample); + }); + }, {once: true}); + }); +})(); diff --git a/static.files/search-39ee4160c7dc16c9.js b/static.files/search-39ee4160c7dc16c9.js new file mode 100644 index 000000000..dd0531c5e --- /dev/null +++ b/static.files/search-39ee4160c7dc16c9.js @@ -0,0 +1,2280 @@ +/* global addClass, getNakedUrl, getSettingValue */ +/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi, exports */ + +"use strict"; + +(function() { +// This mapping table should match the discriminants of +// `rustdoc::formats::item_type::ItemType` type in Rust. +const itemTypes = [ + "mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant", + "associatedconstant", + "union", + "foreigntype", + "keyword", + "existential", + "attr", + "derive", + "traitalias", +]; + +// used for special search precedence +const TY_PRIMITIVE = itemTypes.indexOf("primitive"); +const TY_KEYWORD = itemTypes.indexOf("keyword"); +const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; + +function hasOwnPropertyRustdoc(obj, property) { + return Object.prototype.hasOwnProperty.call(obj, property); +} + +// In the search display, allows to switch between tabs. +function printTab(nb) { + let iter = 0; + let foundCurrentTab = false; + let foundCurrentResultSet = false; + onEachLazy(document.getElementById("titles").childNodes, elem => { + if (nb === iter) { + addClass(elem, "selected"); + foundCurrentTab = true; + } else { + removeClass(elem, "selected"); + } + iter += 1; + }); + iter = 0; + onEachLazy(document.getElementById("results").childNodes, elem => { + if (nb === iter) { + addClass(elem, "active"); + foundCurrentResultSet = true; + } else { + removeClass(elem, "active"); + } + iter += 1; + }); + if (foundCurrentTab && foundCurrentResultSet) { + searchState.currentTab = nb; + } else if (nb !== 0) { + printTab(0); + } +} + +/** + * A function to compute the Levenshtein distance between two strings + * Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported + * Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode + * This code is an unmodified version of the code written by Marco de Wit + * and was found at https://stackoverflow.com/a/18514751/745719 + */ +const levenshtein_row2 = []; +function levenshtein(s1, s2) { + if (s1 === s2) { + return 0; + } + const s1_len = s1.length, s2_len = s2.length; + if (s1_len && s2_len) { + let i1 = 0, i2 = 0, a, b, c, c2; + const row = levenshtein_row2; + while (i1 < s1_len) { + row[i1] = ++i1; + } + while (i2 < s2_len) { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for (i1 = 0; i1 < s1_len; ++i1) { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; + } + } + return b; + } + return s1_len + s2_len; +} + +function initSearch(rawSearchIndex) { + const MAX_LEV_DISTANCE = 3; + const MAX_RESULTS = 200; + const NO_TYPE_FILTER = -1; + /** + * @type {Array} + */ + let searchIndex; + let currentResults; + const ALIASES = Object.create(null); + + function isWhitespace(c) { + return " \t\n\r".indexOf(c) !== -1; + } + + function isSpecialStartCharacter(c) { + return "<\"".indexOf(c) !== -1; + } + + function isEndCharacter(c) { + return ",>-".indexOf(c) !== -1; + } + + function isStopCharacter(c) { + return isWhitespace(c) || isEndCharacter(c); + } + + function isErrorCharacter(c) { + return "()".indexOf(c) !== -1; + } + + function itemTypeFromName(typename) { + for (let i = 0, len = itemTypes.length; i < len; ++i) { + if (itemTypes[i] === typename) { + return i; + } + } + + throw new Error("Unknown type filter `" + typename + "`"); + } + + /** + * If we encounter a `"`, then we try to extract the string from it until we find another `"`. + * + * This function will throw an error in the following cases: + * * There is already another string element. + * * We are parsing a generic argument. + * * There is more than one element. + * * There is no closing `"`. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {boolean} isInGenerics + */ + function getStringElem(query, parserState, isInGenerics) { + if (isInGenerics) { + throw new Error("`\"` cannot be used in generics"); + } else if (query.literalSearch) { + throw new Error("Cannot have more than one literal search element"); + } else if (parserState.totalElems - parserState.genericsElems > 0) { + throw new Error("Cannot use literal search when there is more than one element"); + } + parserState.pos += 1; + const start = parserState.pos; + const end = getIdentEndPosition(parserState); + if (parserState.pos >= parserState.length) { + throw new Error("Unclosed `\"`"); + } else if (parserState.userQuery[end] !== "\"") { + throw new Error(`Unexpected \`${parserState.userQuery[end]}\` in a string element`); + } else if (start === end) { + throw new Error("Cannot have empty string element"); + } + // To skip the quote at the end. + parserState.pos += 1; + query.literalSearch = true; + } + + /** + * Returns `true` if the current parser position is starting with "::". + * + * @param {ParserState} parserState + * + * @return {boolean} + */ + function isPathStart(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) === "::"; + } + + /** + * Returns `true` if the current parser position is starting with "->". + * + * @param {ParserState} parserState + * + * @return {boolean} + */ + function isReturnArrow(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) === "->"; + } + + /** + * Returns `true` if the given `c` character is valid for an ident. + * + * @param {string} c + * + * @return {boolean} + */ + function isIdentCharacter(c) { + return ( + c === "_" || + (c >= "0" && c <= "9") || + (c >= "a" && c <= "z") || + (c >= "A" && c <= "Z")); + } + + /** + * Returns `true` if the given `c` character is a separator. + * + * @param {string} c + * + * @return {boolean} + */ + function isSeparatorCharacter(c) { + return c === "," || isWhitespaceCharacter(c); + } + + /** + * Returns `true` if the given `c` character is a whitespace. + * + * @param {string} c + * + * @return {boolean} + */ + function isWhitespaceCharacter(c) { + return c === " " || c === "\t"; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {string} name - Name of the query element. + * @param {Array} generics - List of generics of this query element. + * + * @return {QueryElement} - The newly created `QueryElement`. + */ + function createQueryElement(query, parserState, name, generics, isInGenerics) { + if (name === "*" || (name.length === 0 && generics.length === 0)) { + return; + } + if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { + throw new Error("You cannot have more than one element if you use quotes"); + } + const pathSegments = name.split("::"); + if (pathSegments.length > 1) { + for (let i = 0, len = pathSegments.length; i < len; ++i) { + const pathSegment = pathSegments[i]; + + if (pathSegment.length === 0) { + if (i === 0) { + throw new Error("Paths cannot start with `::`"); + } else if (i + 1 === len) { + throw new Error("Paths cannot end with `::`"); + } + throw new Error("Unexpected `::::`"); + } + } + } + // In case we only have something like `

    `, there is no name. + if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) { + throw new Error("Found generics without a path"); + } + parserState.totalElems += 1; + if (isInGenerics) { + parserState.genericsElems += 1; + } + return { + name: name, + fullPath: pathSegments, + pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1), + pathLast: pathSegments[pathSegments.length - 1], + generics: generics, + }; + } + + /** + * This function goes through all characters until it reaches an invalid ident character or the + * end of the query. It returns the position of the last character of the ident. + * + * @param {ParserState} parserState + * + * @return {integer} + */ + function getIdentEndPosition(parserState) { + let end = parserState.pos; + let foundExclamation = false; + while (parserState.pos < parserState.length) { + const c = parserState.userQuery[parserState.pos]; + if (!isIdentCharacter(c)) { + if (c === "!") { + if (foundExclamation) { + throw new Error("Cannot have more than one `!` in an ident"); + } else if (parserState.pos + 1 < parserState.length && + isIdentCharacter(parserState.userQuery[parserState.pos + 1]) + ) { + throw new Error("`!` can only be at the end of an ident"); + } + foundExclamation = true; + } else if (isErrorCharacter(c)) { + throw new Error(`Unexpected \`${c}\``); + } else if ( + isStopCharacter(c) || + isSpecialStartCharacter(c) || + isSeparatorCharacter(c) + ) { + break; + } else if (c === ":") { // If we allow paths ("str::string" for example). + if (!isPathStart(parserState)) { + break; + } + // Skip current ":". + parserState.pos += 1; + foundExclamation = false; + } else { + throw new Error(`Unexpected \`${c}\``); + } + } + parserState.pos += 1; + end = parserState.pos; + } + return end; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array} elems - This is where the new {QueryElement} will be added. + * @param {boolean} isInGenerics + */ + function getNextElem(query, parserState, elems, isInGenerics) { + const generics = []; + + let start = parserState.pos; + let end; + // We handle the strings on their own mostly to make code easier to follow. + if (parserState.userQuery[parserState.pos] === "\"") { + start += 1; + getStringElem(query, parserState, isInGenerics); + end = parserState.pos - 1; + } else { + end = getIdentEndPosition(parserState); + } + if (parserState.pos < parserState.length && + parserState.userQuery[parserState.pos] === "<" + ) { + if (isInGenerics) { + throw new Error("Unexpected `<` after `<`"); + } else if (start >= end) { + throw new Error("Found generics without a path"); + } + parserState.pos += 1; + getItemsBefore(query, parserState, generics, ">"); + } + if (start >= end && generics.length === 0) { + return; + } + elems.push( + createQueryElement( + query, + parserState, + parserState.userQuery.slice(start, end), + generics, + isInGenerics + ) + ); + } + + /** + * This function parses the next query element until it finds `endChar`, calling `getNextElem` + * to collect each element. + * + * If there is no `endChar`, this function will implicitly stop at the end without raising an + * error. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array} elems - This is where the new {QueryElement} will be added. + * @param {string} endChar - This function will stop when it'll encounter this + * character. + */ + function getItemsBefore(query, parserState, elems, endChar) { + let foundStopChar = true; + + while (parserState.pos < parserState.length) { + const c = parserState.userQuery[parserState.pos]; + if (c === endChar) { + break; + } else if (isSeparatorCharacter(c)) { + parserState.pos += 1; + foundStopChar = true; + continue; + } else if (c === ":" && isPathStart(parserState)) { + throw new Error("Unexpected `::`: paths cannot start with `::`"); + } else if (c === ":" || isEndCharacter(c)) { + let extra = ""; + if (endChar === ">") { + extra = "`<`"; + } else if (endChar === "") { + extra = "`->`"; + } + throw new Error("Unexpected `" + c + "` after " + extra); + } + if (!foundStopChar) { + if (endChar !== "") { + throw new Error(`Expected \`,\`, \` \` or \`${endChar}\`, found \`${c}\``); + } + throw new Error(`Expected \`,\` or \` \`, found \`${c}\``); + } + const posBefore = parserState.pos; + getNextElem(query, parserState, elems, endChar === ">"); + // This case can be encountered if `getNextElem` encountered a "stop character" right + // from the start. For example if you have `,,` or `<>`. In this case, we simply move up + // the current position to continue the parsing. + if (posBefore === parserState.pos) { + parserState.pos += 1; + } + foundStopChar = false; + } + // We are either at the end of the string or on the `endChar`` character, let's move forward + // in any case. + parserState.pos += 1; + } + + /** + * Checks that the type filter doesn't have unwanted characters like `<>` (which are ignored + * if empty). + * + * @param {ParserState} parserState + */ + function checkExtraTypeFilterCharacters(parserState) { + const query = parserState.userQuery; + + for (let pos = 0; pos < parserState.pos; ++pos) { + if (!isIdentCharacter(query[pos]) && !isWhitespaceCharacter(query[pos])) { + throw new Error(`Unexpected \`${query[pos]}\` in type filter`); + } + } + } + + /** + * Parses the provided `query` input to fill `parserState`. If it encounters an error while + * parsing `query`, it'll throw an error. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + */ + function parseInput(query, parserState) { + let c, before; + let foundStopChar = true; + + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (isStopCharacter(c)) { + foundStopChar = true; + if (isSeparatorCharacter(c)) { + parserState.pos += 1; + continue; + } else if (c === "-" || c === ">") { + if (isReturnArrow(parserState)) { + break; + } + throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`); + } + throw new Error(`Unexpected \`${c}\``); + } else if (c === ":" && !isPathStart(parserState)) { + if (parserState.typeFilter !== null) { + throw new Error("Unexpected `:`"); + } + if (query.elems.length === 0) { + throw new Error("Expected type filter before `:`"); + } else if (query.elems.length !== 1 || parserState.totalElems !== 1) { + throw new Error("Unexpected `:`"); + } else if (query.literalSearch) { + throw new Error("You cannot use quotes on type filter"); + } + checkExtraTypeFilterCharacters(parserState); + // The type filter doesn't count as an element since it's a modifier. + parserState.typeFilter = query.elems.pop().name; + parserState.pos += 1; + parserState.totalElems = 0; + query.literalSearch = false; + foundStopChar = true; + continue; + } + if (!foundStopChar) { + if (parserState.typeFilter !== null) { + throw new Error(`Expected \`,\`, \` \` or \`->\`, found \`${c}\``); + } + throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``); + } + before = query.elems.length; + getNextElem(query, parserState, query.elems, false); + if (query.elems.length === before) { + // Nothing was added, weird... Let's increase the position to not remain stuck. + parserState.pos += 1; + } + foundStopChar = false; + } + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (isReturnArrow(parserState)) { + parserState.pos += 2; + // Get returned elements. + getItemsBefore(query, parserState, query.returned, ""); + // Nothing can come afterward! + if (query.returned.length === 0) { + throw new Error("Expected at least one item after `->`"); + } + break; + } else { + parserState.pos += 1; + } + } + } + + /** + * Takes the user search input and returns an empty `ParsedQuery`. + * + * @param {string} userQuery + * + * @return {ParsedQuery} + */ + function newParsedQuery(userQuery) { + return { + original: userQuery, + userQuery: userQuery.toLowerCase(), + typeFilter: NO_TYPE_FILTER, + elems: [], + returned: [], + // Total number of "top" elements (does not include generics). + foundElems: 0, + literalSearch: false, + error: null, + }; + } + + /** + * Build an URL with search parameters. + * + * @param {string} search - The current search being performed. + * @param {string|null} filterCrates - The current filtering crate (if any). + * + * @return {string} + */ + function buildUrl(search, filterCrates) { + let extra = "?search=" + encodeURIComponent(search); + + if (filterCrates !== null) { + extra += "&filter-crate=" + encodeURIComponent(filterCrates); + } + return getNakedUrl() + extra + window.location.hash; + } + + /** + * Return the filtering crate or `null` if there is none. + * + * @return {string|null} + */ + function getFilterCrates() { + const elem = document.getElementById("crate-search"); + + if (elem && + elem.value !== "all crates" && + hasOwnPropertyRustdoc(rawSearchIndex, elem.value) + ) { + return elem.value; + } + return null; + } + + /** + * Parses the query. + * + * The supported syntax by this parser is as follow: + * + * ident = *(ALPHA / DIGIT / "_") [!] + * path = ident *(DOUBLE-COLON ident) + * arg = path [generics] + * arg-without-generic = path + * type-sep = COMMA/WS *(COMMA/WS) + * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) + * nonempty-arg-list-without-generics = *(type-sep) arg-without-generic + * *(type-sep arg-without-generic) *(type-sep) + * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list-without-generics ] *(type-sep) + * CLOSE-ANGLE-BRACKET/EOF + * return-args = RETURN-ARROW *(type-sep) nonempty-arg-list + * + * exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ] + * type-search = [type-filter *WS COLON] [ nonempty-arg-list ] [ return-args ] + * + * query = *WS (exact-search / type-search) *WS + * + * type-filter = ( + * "mod" / + * "externcrate" / + * "import" / + * "struct" / + * "enum" / + * "fn" / + * "type" / + * "static" / + * "trait" / + * "impl" / + * "tymethod" / + * "method" / + * "structfield" / + * "variant" / + * "macro" / + * "primitive" / + * "associatedtype" / + * "constant" / + * "associatedconstant" / + * "union" / + * "foreigntype" / + * "keyword" / + * "existential" / + * "attr" / + * "derive" / + * "traitalias") + * + * OPEN-ANGLE-BRACKET = "<" + * CLOSE-ANGLE-BRACKET = ">" + * COLON = ":" + * DOUBLE-COLON = "::" + * QUOTE = %x22 + * COMMA = "," + * RETURN-ARROW = "->" + * + * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z + * DIGIT = %x30-39 + * WS = %x09 / " " + * + * @param {string} val - The user query + * + * @return {ParsedQuery} - The parsed query + */ + function parseQuery(userQuery) { + userQuery = userQuery.trim(); + const parserState = { + length: userQuery.length, + pos: 0, + // Total number of elements (includes generics). + totalElems: 0, + genericsElems: 0, + typeFilter: null, + userQuery: userQuery.toLowerCase(), + }; + let query = newParsedQuery(userQuery); + + try { + parseInput(query, parserState); + if (parserState.typeFilter !== null) { + let typeFilter = parserState.typeFilter; + if (typeFilter === "const") { + typeFilter = "constant"; + } + query.typeFilter = itemTypeFromName(typeFilter); + } + } catch (err) { + query = newParsedQuery(userQuery); + query.error = err.message; + query.typeFilter = -1; + return query; + } + + if (!query.literalSearch) { + // If there is more than one element in the query, we switch to literalSearch in any + // case. + query.literalSearch = parserState.totalElems > 1; + } + query.foundElems = query.elems.length + query.returned.length; + return query; + } + + /** + * Creates the query results. + * + * @param {Array} results_in_args + * @param {Array} results_returned + * @param {Array} results_in_args + * @param {ParsedQuery} parsedQuery + * + * @return {ResultsTable} + */ + function createQueryResults(results_in_args, results_returned, results_others, parsedQuery) { + return { + "in_args": results_in_args, + "returned": results_returned, + "others": results_others, + "query": parsedQuery, + }; + } + + /** + * Executes the parsed query and builds a {ResultsTable}. + * + * @param {ParsedQuery} parsedQuery - The parsed user query + * @param {Object} searchWords - The list of search words to query against + * @param {Object} [filterCrates] - Crate to search in if defined + * @param {Object} [currentCrate] - Current crate, to rank results from this crate higher + * + * @return {ResultsTable} + */ + function execQuery(parsedQuery, searchWords, filterCrates, currentCrate) { + const results_others = {}, results_in_args = {}, results_returned = {}; + + function transformResults(results) { + const duplicates = {}; + const out = []; + + for (const result of results) { + if (result.id > -1) { + const obj = searchIndex[result.id]; + obj.lev = result.lev; + const res = buildHrefAndPath(obj); + obj.displayPath = pathSplitter(res[0]); + obj.fullPath = obj.displayPath + obj.name; + // To be sure than it some items aren't considered as duplicate. + obj.fullPath += "|" + obj.ty; + + if (duplicates[obj.fullPath]) { + continue; + } + duplicates[obj.fullPath] = true; + + obj.href = res[1]; + out.push(obj); + if (out.length >= MAX_RESULTS) { + break; + } + } + } + return out; + } + + function sortResults(results, isType, preferredCrate) { + const userQuery = parsedQuery.userQuery; + const ar = []; + for (const entry in results) { + if (hasOwnPropertyRustdoc(results, entry)) { + const result = results[entry]; + result.word = searchWords[result.id]; + result.item = searchIndex[result.id] || {}; + ar.push(result); + } + } + results = ar; + // if there are no results then return to default and fail + if (results.length === 0) { + return []; + } + + results.sort((aaa, bbb) => { + let a, b; + + // sort by exact match with regard to the last word (mismatch goes later) + a = (aaa.word !== userQuery); + b = (bbb.word !== userQuery); + if (a !== b) { + return a - b; + } + + // Sort by non levenshtein results and then levenshtein results by the distance + // (less changes required to match means higher rankings) + a = (aaa.lev); + b = (bbb.lev); + if (a !== b) { + return a - b; + } + + // sort by crate (current crate comes first) + a = (aaa.item.crate !== preferredCrate); + b = (bbb.item.crate !== preferredCrate); + if (a !== b) { + return a - b; + } + + // sort by item name length (longer goes later) + a = aaa.word.length; + b = bbb.word.length; + if (a !== b) { + return a - b; + } + + // sort by item name (lexicographically larger goes later) + a = aaa.word; + b = bbb.word; + if (a !== b) { + return (a > b ? +1 : -1); + } + + // sort by index of keyword in item name (no literal occurrence goes later) + a = (aaa.index < 0); + b = (bbb.index < 0); + if (a !== b) { + return a - b; + } + // (later literal occurrence, if any, goes later) + a = aaa.index; + b = bbb.index; + if (a !== b) { + return a - b; + } + + // special precedence for primitive and keyword pages + if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) || + (aaa.item.ty === TY_KEYWORD && bbb.item.ty !== TY_PRIMITIVE)) { + return -1; + } + if ((bbb.item.ty === TY_PRIMITIVE && aaa.item.ty !== TY_PRIMITIVE) || + (bbb.item.ty === TY_KEYWORD && aaa.item.ty !== TY_KEYWORD)) { + return 1; + } + + // sort by description (no description goes later) + a = (aaa.item.desc === ""); + b = (bbb.item.desc === ""); + if (a !== b) { + return a - b; + } + + // sort by type (later occurrence in `itemTypes` goes later) + a = aaa.item.ty; + b = bbb.item.ty; + if (a !== b) { + return a - b; + } + + // sort by path (lexicographically larger goes later) + a = aaa.item.path; + b = bbb.item.path; + if (a !== b) { + return (a > b ? +1 : -1); + } + + // que sera, sera + return 0; + }); + + let nameSplit = null; + if (parsedQuery.elems.length === 1) { + const hasPath = typeof parsedQuery.elems[0].path === "undefined"; + nameSplit = hasPath ? null : parsedQuery.elems[0].path; + } + + for (const result of results) { + // this validation does not make sense when searching by types + if (result.dontValidate) { + continue; + } + const name = result.item.name.toLowerCase(), + path = result.item.path.toLowerCase(), + parent = result.item.parent; + + if (!isType && !validateResult(name, path, nameSplit, parent)) { + result.id = -1; + } + } + return transformResults(results); + } + + /** + * This function checks if the object (`row`) generics match the given type (`elem`) + * generics. If there are no generics on `row`, `defaultLev` is returned. + * + * @param {Row} row - The object to check. + * @param {QueryElement} elem - The element from the parsed query. + * @param {integer} defaultLev - This is the value to return in case there are no generics. + * + * @return {integer} - Returns the best match (if any) or `MAX_LEV_DISTANCE + 1`. + */ + function checkGenerics(row, elem, defaultLev) { + if (row.generics.length === 0) { + return elem.generics.length === 0 ? defaultLev : MAX_LEV_DISTANCE + 1; + } else if (row.generics.length > 0 && row.generics[0].name === null) { + return checkGenerics(row.generics[0], elem, defaultLev); + } + // The names match, but we need to be sure that all generics kinda + // match as well. + let elem_name; + if (elem.generics.length > 0 && row.generics.length >= elem.generics.length) { + const elems = Object.create(null); + for (const entry of row.generics) { + elem_name = entry.name; + if (elem_name === "") { + // Pure generic, needs to check into it. + if (checkGenerics(entry, elem, MAX_LEV_DISTANCE + 1) !== 0) { + return MAX_LEV_DISTANCE + 1; + } + continue; + } + if (elems[elem_name] === undefined) { + elems[elem_name] = 0; + } + elems[elem_name] += 1; + } + // We need to find the type that matches the most to remove it in order + // to move forward. + for (const generic of elem.generics) { + let match = null; + if (elems[generic.name]) { + match = generic.name; + } else { + for (elem_name in elems) { + if (!hasOwnPropertyRustdoc(elems, elem_name)) { + continue; + } + if (elem_name === generic) { + match = elem_name; + break; + } + } + } + if (match === null) { + return MAX_LEV_DISTANCE + 1; + } + elems[match] -= 1; + if (elems[match] === 0) { + delete elems[match]; + } + } + return 0; + } + return MAX_LEV_DISTANCE + 1; + } + + /** + * This function checks if the object (`row`) matches the given type (`elem`) and its + * generics (if any). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * + * @return {integer} - Returns a Levenshtein distance to the best match. + */ + function checkIfInGenerics(row, elem) { + let lev = MAX_LEV_DISTANCE + 1; + for (const entry of row.generics) { + lev = Math.min(checkType(entry, elem, true), lev); + if (lev === 0) { + break; + } + } + return lev; + } + + /** + * This function checks if the object (`row`) matches the given type (`elem`) and its + * generics (if any). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * @param {boolean} literalSearch + * + * @return {integer} - Returns a Levenshtein distance to the best match. If there is + * no match, returns `MAX_LEV_DISTANCE + 1`. + */ + function checkType(row, elem, literalSearch) { + if (row.name === null) { + // This is a pure "generic" search, no need to run other checks. + if (row.generics.length > 0) { + return checkIfInGenerics(row, elem); + } + return MAX_LEV_DISTANCE + 1; + } + + let lev = levenshtein(row.name, elem.name); + if (literalSearch) { + if (lev !== 0) { + // The name didn't match, let's try to check if the generics do. + if (elem.generics.length === 0) { + const checkGeneric = row.generics.length > 0; + if (checkGeneric && row.generics + .findIndex(tmp_elem => tmp_elem.name === elem.name) !== -1) { + return 0; + } + } + return MAX_LEV_DISTANCE + 1; + } else if (elem.generics.length > 0) { + return checkGenerics(row, elem, MAX_LEV_DISTANCE + 1); + } + return 0; + } else if (row.generics.length > 0) { + if (elem.generics.length === 0) { + if (lev === 0) { + return 0; + } + // The name didn't match so we now check if the type we're looking for is inside + // the generics! + lev = checkIfInGenerics(row, elem); + // Now whatever happens, the returned distance is "less good" so we should mark + // it as such, and so we add 0.5 to the distance to make it "less good". + return lev + 0.5; + } else if (lev > MAX_LEV_DISTANCE) { + // So our item's name doesn't match at all and has generics. + // + // Maybe it's present in a sub generic? For example "f>>()", if we're + // looking for "B", we'll need to go down. + return checkIfInGenerics(row, elem); + } else { + // At this point, the name kinda match and we have generics to check, so + // let's go! + const tmp_lev = checkGenerics(row, elem, lev); + if (tmp_lev > MAX_LEV_DISTANCE) { + return MAX_LEV_DISTANCE + 1; + } + // We compute the median value of both checks and return it. + return (tmp_lev + lev) / 2; + } + } else if (elem.generics.length > 0) { + // In this case, we were expecting generics but there isn't so we simply reject this + // one. + return MAX_LEV_DISTANCE + 1; + } + // No generics on our query or on the target type so we can return without doing + // anything else. + return lev; + } + + /** + * This function checks if the object (`row`) has an argument with the given type (`elem`). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * @param {integer} typeFilter + * + * @return {integer} - Returns a Levenshtein distance to the best match. If there is no + * match, returns `MAX_LEV_DISTANCE + 1`. + */ + function findArg(row, elem, typeFilter) { + let lev = MAX_LEV_DISTANCE + 1; + + if (row && row.type && row.type.inputs && row.type.inputs.length > 0) { + for (const input of row.type.inputs) { + if (!typePassesFilter(typeFilter, input.ty)) { + continue; + } + lev = Math.min(lev, checkType(input, elem, parsedQuery.literalSearch)); + if (lev === 0) { + return 0; + } + } + } + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; + } + + /** + * This function checks if the object (`row`) returns the given type (`elem`). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * @param {integer} typeFilter + * + * @return {integer} - Returns a Levenshtein distance to the best match. If there is no + * match, returns `MAX_LEV_DISTANCE + 1`. + */ + function checkReturned(row, elem, typeFilter) { + let lev = MAX_LEV_DISTANCE + 1; + + if (row && row.type && row.type.output.length > 0) { + const ret = row.type.output; + for (const ret_ty of ret) { + if (!typePassesFilter(typeFilter, ret_ty.ty)) { + continue; + } + lev = Math.min(lev, checkType(ret_ty, elem, parsedQuery.literalSearch)); + if (lev === 0) { + return 0; + } + } + } + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; + } + + function checkPath(contains, ty) { + if (contains.length === 0) { + return 0; + } + let ret_lev = MAX_LEV_DISTANCE + 1; + const path = ty.path.split("::"); + + if (ty.parent && ty.parent.name) { + path.push(ty.parent.name.toLowerCase()); + } + + const length = path.length; + const clength = contains.length; + if (clength > length) { + return MAX_LEV_DISTANCE + 1; + } + for (let i = 0; i < length; ++i) { + if (i + clength > length) { + break; + } + let lev_total = 0; + let aborted = false; + for (let x = 0; x < clength; ++x) { + const lev = levenshtein(path[i + x], contains[x]); + if (lev > MAX_LEV_DISTANCE) { + aborted = true; + break; + } + lev_total += lev; + } + if (!aborted) { + ret_lev = Math.min(ret_lev, Math.round(lev_total / clength)); + } + } + return ret_lev; + } + + function typePassesFilter(filter, type) { + // No filter or Exact mach + if (filter <= NO_TYPE_FILTER || filter === type) return true; + + // Match related items + const name = itemTypes[type]; + switch (itemTypes[filter]) { + case "constant": + return name === "associatedconstant"; + case "fn": + return name === "method" || name === "tymethod"; + case "type": + return name === "primitive" || name === "associatedtype"; + case "trait": + return name === "traitalias"; + } + + // No match + return false; + } + + function createAliasFromItem(item) { + return { + crate: item.crate, + name: item.name, + path: item.path, + desc: item.desc, + ty: item.ty, + parent: item.parent, + type: item.type, + is_alias: true, + }; + } + + function handleAliases(ret, query, filterCrates, currentCrate) { + const lowerQuery = query.toLowerCase(); + // We separate aliases and crate aliases because we want to have current crate + // aliases to be before the others in the displayed results. + const aliases = []; + const crateAliases = []; + if (filterCrates !== null) { + if (ALIASES[filterCrates] && ALIASES[filterCrates][lowerQuery]) { + const query_aliases = ALIASES[filterCrates][lowerQuery]; + for (const alias of query_aliases) { + aliases.push(createAliasFromItem(searchIndex[alias])); + } + } + } else { + Object.keys(ALIASES).forEach(crate => { + if (ALIASES[crate][lowerQuery]) { + const pushTo = crate === currentCrate ? crateAliases : aliases; + const query_aliases = ALIASES[crate][lowerQuery]; + for (const alias of query_aliases) { + pushTo.push(createAliasFromItem(searchIndex[alias])); + } + } + }); + } + + const sortFunc = (aaa, bbb) => { + if (aaa.path < bbb.path) { + return 1; + } else if (aaa.path === bbb.path) { + return 0; + } + return -1; + }; + crateAliases.sort(sortFunc); + aliases.sort(sortFunc); + + const pushFunc = alias => { + alias.alias = query; + const res = buildHrefAndPath(alias); + alias.displayPath = pathSplitter(res[0]); + alias.fullPath = alias.displayPath + alias.name; + alias.href = res[1]; + + ret.others.unshift(alias); + if (ret.others.length > MAX_RESULTS) { + ret.others.pop(); + } + }; + + aliases.forEach(pushFunc); + crateAliases.forEach(pushFunc); + } + + /** + * This function adds the given result into the provided `results` map if it matches the + * following condition: + * + * * If it is a "literal search" (`parsedQuery.literalSearch`), then `lev` must be 0. + * * If it is not a "literal search", `lev` must be <= `MAX_LEV_DISTANCE`. + * + * The `results` map contains information which will be used to sort the search results: + * + * * `fullId` is a `string`` used as the key of the object we use for the `results` map. + * * `id` is the index in both `searchWords` and `searchIndex` arrays for this element. + * * `index` is an `integer`` used to sort by the position of the word in the item's name. + * * `lev` is the main metric used to sort the search results. + * + * @param {Results} results + * @param {string} fullId + * @param {integer} id + * @param {integer} index + * @param {integer} lev + */ + function addIntoResults(results, fullId, id, index, lev) { + if (lev === 0 || (!parsedQuery.literalSearch && lev <= MAX_LEV_DISTANCE)) { + if (results[fullId] !== undefined) { + const result = results[fullId]; + if (result.dontValidate || result.lev <= lev) { + return; + } + } + results[fullId] = { + id: id, + index: index, + dontValidate: parsedQuery.literalSearch, + lev: lev, + }; + } + } + + /** + * This function is called in case the query is only one element (with or without generics). + * This element will be compared to arguments' and returned values' items and also to items. + * + * Other important thing to note: since there is only one element, we use levenshtein + * distance for name comparisons. + * + * @param {Row} row + * @param {integer} pos - Position in the `searchIndex`. + * @param {QueryElement} elem - The element from the parsed query. + * @param {Results} results_others - Unqualified results (not in arguments nor in + * returned values). + * @param {Results} results_in_args - Matching arguments results. + * @param {Results} results_returned - Matching returned arguments results. + */ + function handleSingleArg( + row, + pos, + elem, + results_others, + results_in_args, + results_returned + ) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { + return; + } + let lev, lev_add = 0, index = -1; + const fullId = row.id; + + const in_args = findArg(row, elem, parsedQuery.typeFilter); + const returned = checkReturned(row, elem, parsedQuery.typeFilter); + + addIntoResults(results_in_args, fullId, pos, index, in_args); + addIntoResults(results_returned, fullId, pos, index, returned); + + if (!typePassesFilter(parsedQuery.typeFilter, row.ty)) { + return; + } + const searchWord = searchWords[pos]; + + if (parsedQuery.literalSearch) { + if (searchWord === elem.name) { + addIntoResults(results_others, fullId, pos, -1, 0); + } + return; + } + + // No need to check anything else if it's a "pure" generics search. + if (elem.name.length === 0) { + if (row.type !== null) { + lev = checkGenerics(row.type, elem, MAX_LEV_DISTANCE + 1); + addIntoResults(results_others, fullId, pos, index, lev); + } + return; + } + + if (elem.fullPath.length > 1) { + lev = checkPath(elem.pathWithoutLast, row); + if (lev > MAX_LEV_DISTANCE || (parsedQuery.literalSearch && lev !== 0)) { + return; + } else if (lev > 0) { + lev_add = lev / 10; + } + } + + if (searchWord.indexOf(elem.pathLast) > -1 || + row.normalizedName.indexOf(elem.pathLast) > -1 + ) { + index = row.normalizedName.indexOf(elem.pathLast); + } + lev = levenshtein(searchWord, elem.pathLast); + if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) { + if (elem.pathLast.length < 6) { + lev = 1; + } else { + lev = 0; + } + } + lev += lev_add; + if (lev > MAX_LEV_DISTANCE) { + return; + } else if (index !== -1 && elem.fullPath.length < 2) { + lev -= 1; + } + if (lev < 0) { + lev = 0; + } + addIntoResults(results_others, fullId, pos, index, lev); + } + + /** + * This function is called in case the query has more than one element. In this case, it'll + * try to match the items which validates all the elements. For `aa -> bb` will look for + * functions which have a parameter `aa` and has `bb` in its returned values. + * + * @param {Row} row + * @param {integer} pos - Position in the `searchIndex`. + * @param {Object} results + */ + function handleArgs(row, pos, results) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { + return; + } + + let totalLev = 0; + let nbLev = 0; + + // If the result is too "bad", we return false and it ends this search. + function checkArgs(elems, callback) { + for (const elem of elems) { + // There is more than one parameter to the query so all checks should be "exact" + const lev = callback(row, elem, NO_TYPE_FILTER); + if (lev <= 1) { + nbLev += 1; + totalLev += lev; + } else { + return false; + } + } + return true; + } + if (!checkArgs(parsedQuery.elems, findArg)) { + return; + } + if (!checkArgs(parsedQuery.returned, checkReturned)) { + return; + } + + if (nbLev === 0) { + return; + } + const lev = Math.round(totalLev / nbLev); + addIntoResults(results, row.id, pos, 0, lev); + } + + function innerRunQuery() { + let elem, i, nSearchWords, in_returned, row; + + if (parsedQuery.foundElems === 1) { + if (parsedQuery.elems.length === 1) { + elem = parsedQuery.elems[0]; + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + // It means we want to check for this element everywhere (in names, args and + // returned). + handleSingleArg( + searchIndex[i], + i, + elem, + results_others, + results_in_args, + results_returned + ); + } + } else if (parsedQuery.returned.length === 1) { + // We received one returned argument to check, so looking into returned values. + elem = parsedQuery.returned[0]; + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + row = searchIndex[i]; + in_returned = checkReturned(row, elem, parsedQuery.typeFilter); + addIntoResults(results_others, row.id, i, -1, in_returned); + } + } + } else if (parsedQuery.foundElems > 0) { + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + handleArgs(searchIndex[i], i, results_others); + } + } + } + + if (parsedQuery.error === null) { + innerRunQuery(); + } + + const ret = createQueryResults( + sortResults(results_in_args, true, currentCrate), + sortResults(results_returned, true, currentCrate), + sortResults(results_others, false, currentCrate), + parsedQuery); + handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates, currentCrate); + if (parsedQuery.error !== null && ret.others.length !== 0) { + // It means some doc aliases were found so let's "remove" the error! + ret.query.error = null; + } + return ret; + } + + /** + * Validate performs the following boolean logic. For example: + * "File::open" will give IF A PARENT EXISTS => ("file" && "open") + * exists in (name || path || parent) OR => ("file" && "open") exists in + * (name || path ) + * + * This could be written functionally, but I wanted to minimise + * functions on stack. + * + * @param {string} name - The name of the result + * @param {string} path - The path of the result + * @param {string} keys - The keys to be used (["file", "open"]) + * @param {Object} parent - The parent of the result + * + * @return {boolean} - Whether the result is valid or not + */ + function validateResult(name, path, keys, parent) { + if (!keys || !keys.length) { + return true; + } + for (const key of keys) { + // each check is for validation so we negate the conditions and invalidate + if (!( + // check for an exact name match + name.indexOf(key) > -1 || + // then an exact path match + path.indexOf(key) > -1 || + // next if there is a parent, check for exact parent match + (parent !== undefined && parent.name !== undefined && + parent.name.toLowerCase().indexOf(key) > -1) || + // lastly check to see if the name was a levenshtein match + levenshtein(name, key) <= MAX_LEV_DISTANCE)) { + return false; + } + } + return true; + } + + function nextTab(direction) { + const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length; + searchState.focusedByTab[searchState.currentTab] = document.activeElement; + printTab(next); + focusSearchResult(); + } + + // Focus the first search result on the active tab, or the result that + // was focused last time this tab was active. + function focusSearchResult() { + const target = searchState.focusedByTab[searchState.currentTab] || + document.querySelectorAll(".search-results.active a").item(0) || + document.querySelectorAll("#titles > button").item(searchState.currentTab); + if (target) { + target.focus(); + } + } + + function buildHrefAndPath(item) { + let displayPath; + let href; + const type = itemTypes[item.ty]; + const name = item.name; + let path = item.path; + + if (type === "mod") { + displayPath = path + "::"; + href = ROOT_PATH + path.replace(/::/g, "/") + "/" + + name + "/index.html"; + } else if (type === "import") { + displayPath = item.path + "::"; + href = ROOT_PATH + item.path.replace(/::/g, "/") + "/index.html#reexport." + name; + } else if (type === "primitive" || type === "keyword") { + displayPath = ""; + href = ROOT_PATH + path.replace(/::/g, "/") + + "/" + type + "." + name + ".html"; + } else if (type === "externcrate") { + displayPath = ""; + href = ROOT_PATH + name + "/index.html"; + } else if (item.parent !== undefined) { + const myparent = item.parent; + let anchor = "#" + type + "." + name; + const parentType = itemTypes[myparent.ty]; + let pageType = parentType; + let pageName = myparent.name; + + if (parentType === "primitive") { + displayPath = myparent.name + "::"; + } else if (type === "structfield" && parentType === "variant") { + // Structfields belonging to variants are special: the + // final path element is the enum name. + const enumNameIdx = item.path.lastIndexOf("::"); + const enumName = item.path.substr(enumNameIdx + 2); + path = item.path.substr(0, enumNameIdx); + displayPath = path + "::" + enumName + "::" + myparent.name + "::"; + anchor = "#variant." + myparent.name + ".field." + name; + pageType = "enum"; + pageName = enumName; + } else { + displayPath = path + "::" + myparent.name + "::"; + } + href = ROOT_PATH + path.replace(/::/g, "/") + + "/" + pageType + + "." + pageName + + ".html" + anchor; + } else { + displayPath = item.path + "::"; + href = ROOT_PATH + item.path.replace(/::/g, "/") + + "/" + type + "." + name + ".html"; + } + return [displayPath, href]; + } + + function pathSplitter(path) { + const tmp = "" + path.replace(/::/g, "::"); + if (tmp.endsWith("")) { + return tmp.slice(0, tmp.length - 6); + } + return tmp; + } + + /** + * Render a set of search results for a single tab. + * @param {Array} array - The search results for this tab + * @param {ParsedQuery} query + * @param {boolean} display - True if this is the active tab + */ + function addTab(array, query, display) { + let extraClass = ""; + if (display === true) { + extraClass = " active"; + } + + const output = document.createElement("div"); + let length = 0; + if (array.length > 0) { + output.className = "search-results " + extraClass; + + array.forEach(item => { + const name = item.name; + const type = itemTypes[item.ty]; + + length += 1; + + let extra = ""; + if (type === "primitive") { + extra = " (primitive type)"; + } else if (type === "keyword") { + extra = " (keyword)"; + } + + const link = document.createElement("a"); + link.className = "result-" + type; + link.href = item.href; + + const resultName = document.createElement("div"); + resultName.className = "result-name"; + + if (item.is_alias) { + const alias = document.createElement("span"); + alias.className = "alias"; + + const bold = document.createElement("b"); + bold.innerText = item.alias; + alias.appendChild(bold); + + alias.insertAdjacentHTML( + "beforeend", + " - see "); + + resultName.appendChild(alias); + } + resultName.insertAdjacentHTML( + "beforeend", + item.displayPath + "" + name + extra + ""); + link.appendChild(resultName); + + const description = document.createElement("div"); + description.className = "desc"; + description.insertAdjacentHTML("beforeend", item.desc); + + link.appendChild(description); + output.appendChild(link); + }); + } else if (query.error === null) { + output.className = "search-failed" + extraClass; + output.innerHTML = "No results :(
    " + + "Try on DuckDuckGo?

    " + + "Or try looking in one of these:

    "; + } + return [output, length]; + } + + function makeTabHeader(tabNb, text, nbElems) { + if (searchState.currentTab === tabNb) { + return ""; + } + return ""; + } + + /** + * @param {ResultsTable} results + * @param {boolean} go_to_first + * @param {string} filterCrates + */ + function showResults(results, go_to_first, filterCrates) { + const search = searchState.outputElement(); + if (go_to_first || (results.others.length === 1 + && getSettingValue("go-to-only-result") === "true" + // By default, the search DOM element is "empty" (meaning it has no children not + // text content). Once a search has been run, it won't be empty, even if you press + // ESC or empty the search input (which also "cancels" the search). + && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)) + ) { + const elem = document.createElement("a"); + elem.href = results.others[0].href; + removeClass(elem, "active"); + // For firefox, we need the element to be in the DOM so it can be clicked. + document.body.appendChild(elem); + elem.click(); + return; + } + if (results.query === undefined) { + results.query = parseQuery(searchState.input.value); + } + + currentResults = results.query.userQuery; + + const ret_others = addTab(results.others, results.query, true); + const ret_in_args = addTab(results.in_args, results.query, false); + const ret_returned = addTab(results.returned, results.query, false); + + // Navigate to the relevant tab if the current tab is empty, like in case users search + // for "-> String". If they had selected another tab previously, they have to click on + // it again. + let currentTab = searchState.currentTab; + if ((currentTab === 0 && ret_others[1] === 0) || + (currentTab === 1 && ret_in_args[1] === 0) || + (currentTab === 2 && ret_returned[1] === 0)) { + if (ret_others[1] !== 0) { + currentTab = 0; + } else if (ret_in_args[1] !== 0) { + currentTab = 1; + } else if (ret_returned[1] !== 0) { + currentTab = 2; + } + } + + let crates = ""; + const crates_list = Object.keys(rawSearchIndex); + if (crates_list.length > 1) { + crates = " in 
    "; + } + + let output = `

    Results${crates}

    `; + if (results.query.error !== null) { + output += `

    Query parser error: "${results.query.error}".

    `; + output += "
    " + + makeTabHeader(0, "In Names", ret_others[1]) + + "
    "; + currentTab = 0; + } else if (results.query.foundElems <= 1 && results.query.returned.length === 0) { + output += "
    " + + makeTabHeader(0, "In Names", ret_others[1]) + + makeTabHeader(1, "In Parameters", ret_in_args[1]) + + makeTabHeader(2, "In Return Types", ret_returned[1]) + + "
    "; + } else { + const signatureTabTitle = + results.query.elems.length === 0 ? "In Function Return Types" : + results.query.returned.length === 0 ? "In Function Parameters" : + "In Function Signatures"; + output += "
    " + + makeTabHeader(0, signatureTabTitle, ret_others[1]) + + "
    "; + currentTab = 0; + } + + const resultsElem = document.createElement("div"); + resultsElem.id = "results"; + resultsElem.appendChild(ret_others[0]); + resultsElem.appendChild(ret_in_args[0]); + resultsElem.appendChild(ret_returned[0]); + + search.innerHTML = output; + const crateSearch = document.getElementById("crate-search"); + if (crateSearch) { + crateSearch.addEventListener("input", updateCrate); + } + search.appendChild(resultsElem); + // Reset focused elements. + searchState.showResults(search); + const elems = document.getElementById("titles").childNodes; + searchState.focusedByTab = []; + let i = 0; + for (const elem of elems) { + const j = i; + elem.onclick = () => printTab(j); + searchState.focusedByTab.push(null); + i += 1; + } + printTab(currentTab); + } + + /** + * Perform a search based on the current state of the search input element + * and display the results. + * @param {Event} [e] - The event that triggered this search, if any + * @param {boolean} [forced] + */ + function search(e, forced) { + const params = searchState.getQueryStringParams(); + const query = parseQuery(searchState.input.value.trim()); + + if (e) { + e.preventDefault(); + } + + if (!forced && query.userQuery === currentResults) { + if (query.userQuery.length > 0) { + putBackSearch(); + } + return; + } + + let filterCrates = getFilterCrates(); + + // In case we have no information about the saved crate and there is a URL query parameter, + // we override it with the URL query parameter. + if (filterCrates === null && params["filter-crate"] !== undefined) { + filterCrates = params["filter-crate"]; + } + + // Update document title to maintain a meaningful browser history + searchState.title = "Results for " + query.original + " - Rust"; + + // Because searching is incremental by character, only the most + // recent search query is added to the browser history. + if (browserSupportsHistoryApi()) { + const newURL = buildUrl(query.original, filterCrates); + + if (!history.state && !params.search) { + history.pushState(null, "", newURL); + } else { + history.replaceState(null, "", newURL); + } + } + + showResults( + execQuery(query, searchWords, filterCrates, window.currentCrate), + params.go_to_first, + filterCrates); + } + + /** + * Convert a list of RawFunctionType / ID to object-based FunctionType. + * + * Crates often have lots of functions in them, and it's common to have a large number of + * functions that operate on a small set of data types, so the search index compresses them + * by encoding function parameter and return types as indexes into an array of names. + * + * Even when a general-purpose compression algorithm is used, this is still a win. I checked. + * https://github.com/rust-lang/rust/pull/98475#issue-1284395985 + * + * The format for individual function types is encoded in + * librustdoc/html/render/mod.rs: impl Serialize for RenderType + * + * @param {null|Array} types + * @param {Array<{name: string, ty: number}>} lowercasePaths + * + * @return {Array} + */ + function buildItemSearchTypeAll(types, lowercasePaths) { + const PATH_INDEX_DATA = 0; + const GENERICS_DATA = 1; + return types.map(type => { + let pathIndex, generics; + if (typeof type === "number") { + pathIndex = type; + generics = []; + } else { + pathIndex = type[PATH_INDEX_DATA]; + generics = buildItemSearchTypeAll(type[GENERICS_DATA], lowercasePaths); + } + return { + // `0` is used as a sentinel because it's fewer bytes than `null` + name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, + generics: generics, + }; + }); + } + + /** + * Convert from RawFunctionSearchType to FunctionSearchType. + * + * Crates often have lots of functions in them, and function signatures are sometimes complex, + * so rustdoc uses a pretty tight encoding for them. This function converts it to a simpler, + * object-based encoding so that the actual search code is more readable and easier to debug. + * + * The raw function search type format is generated using serde in + * librustdoc/html/render/mod.rs: impl Serialize for IndexItemFunctionType + * + * @param {RawFunctionSearchType} functionSearchType + * @param {Array<{name: string, ty: number}>} lowercasePaths + * + * @return {null|FunctionSearchType} + */ + function buildFunctionSearchType(functionSearchType, lowercasePaths) { + const INPUTS_DATA = 0; + const OUTPUT_DATA = 1; + // `0` is used as a sentinel because it's fewer bytes than `null` + if (functionSearchType === 0) { + return null; + } + let inputs, output; + if (typeof functionSearchType[INPUTS_DATA] === "number") { + const pathIndex = functionSearchType[INPUTS_DATA]; + inputs = [{ + name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, + generics: [], + }]; + } else { + inputs = buildItemSearchTypeAll(functionSearchType[INPUTS_DATA], lowercasePaths); + } + if (functionSearchType.length > 1) { + if (typeof functionSearchType[OUTPUT_DATA] === "number") { + const pathIndex = functionSearchType[OUTPUT_DATA]; + output = [{ + name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, + generics: [], + }]; + } else { + output = buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA], lowercasePaths); + } + } else { + output = []; + } + return { + inputs, output, + }; + } + + function buildIndex(rawSearchIndex) { + searchIndex = []; + /** + * @type {Array} + */ + const searchWords = []; + let i, word; + let currentIndex = 0; + let id = 0; + + for (const crate in rawSearchIndex) { + if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { + continue; + } + + let crateSize = 0; + + /** + * The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f` + * are arrays with the same length. n[i] contains the name of an item. + * t[i] contains the type of that item (as a small integer that represents an + * offset in `itemTypes`). d[i] contains the description of that item. + * + * q[i] contains the full path of the item, or an empty string indicating + * "same as q[i-1]". + * + * i[i] contains an item's parent, usually a module. For compactness, + * it is a set of indexes into the `p` array. + * + * f[i] contains function signatures, or `0` if the item isn't a function. + * Functions are themselves encoded as arrays. The first item is a list of + * types representing the function's inputs, and the second list item is a list + * of types representing the function's output. Tuples are flattened. + * Types are also represented as arrays; the first item is an index into the `p` + * array, while the second is a list of types representing any generic parameters. + * + * `a` defines aliases with an Array of pairs: [name, offset], where `offset` + * points into the n/t/d/q/i/f arrays. + * + * `doc` contains the description of the crate. + * + * `p` is a list of path/type pairs. It is used for parents and function parameters. + * + * @type {{ + * doc: string, + * a: Object, + * n: Array, + * t: Array, + * d: Array, + * q: Array, + * i: Array, + * f: Array, + * p: Array, + * }} + */ + const crateCorpus = rawSearchIndex[crate]; + + searchWords.push(crate); + // This object should have exactly the same set of fields as the "row" + // object defined below. Your JavaScript runtime will thank you. + // https://mathiasbynens.be/notes/shapes-ics + const crateRow = { + crate: crate, + ty: 1, // == ExternCrate + name: crate, + path: "", + desc: crateCorpus.doc, + parent: undefined, + type: null, + id: id, + normalizedName: crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""), + }; + id += 1; + searchIndex.push(crateRow); + currentIndex += 1; + + // an array of (Number) item types + const itemTypes = crateCorpus.t; + // an array of (String) item names + const itemNames = crateCorpus.n; + // an array of (String) full paths (or empty string for previous path) + const itemPaths = crateCorpus.q; + // an array of (String) descriptions + const itemDescs = crateCorpus.d; + // an array of (Number) the parent path index + 1 to `paths`, or 0 if none + const itemParentIdxs = crateCorpus.i; + // an array of (Object | null) the type of the function, if any + const itemFunctionSearchTypes = crateCorpus.f; + // an array of [(Number) item type, + // (String) name] + const paths = crateCorpus.p; + // an array of [(String) alias name + // [Number] index to items] + const aliases = crateCorpus.a; + + // an array of [{name: String, ty: Number}] + const lowercasePaths = []; + + // convert `rawPaths` entries into object form + // generate normalizedPaths for function search mode + let len = paths.length; + for (i = 0; i < len; ++i) { + lowercasePaths.push({ty: paths[i][0], name: paths[i][1].toLowerCase()}); + paths[i] = {ty: paths[i][0], name: paths[i][1]}; + } + + // convert `item*` into an object form, and construct word indices. + // + // before any analysis is performed lets gather the search terms to + // search against apart from the rest of the data. This is a quick + // operation that is cached for the life of the page state so that + // all other search operations have access to this cached data for + // faster analysis operations + len = itemTypes.length; + let lastPath = ""; + for (i = 0; i < len; ++i) { + // This object should have exactly the same set of fields as the "crateRow" + // object defined above. + if (typeof itemNames[i] === "string") { + word = itemNames[i].toLowerCase(); + searchWords.push(word); + } else { + word = ""; + searchWords.push(""); + } + const row = { + crate: crate, + ty: itemTypes[i], + name: itemNames[i], + path: itemPaths[i] ? itemPaths[i] : lastPath, + desc: itemDescs[i], + parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, + type: buildFunctionSearchType(itemFunctionSearchTypes[i], lowercasePaths), + id: id, + normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), + }; + id += 1; + searchIndex.push(row); + lastPath = row.path; + crateSize += 1; + } + + if (aliases) { + ALIASES[crate] = Object.create(null); + for (const alias_name in aliases) { + if (!hasOwnPropertyRustdoc(aliases, alias_name)) { + continue; + } + + if (!hasOwnPropertyRustdoc(ALIASES[crate], alias_name)) { + ALIASES[crate][alias_name] = []; + } + for (const local_alias of aliases[alias_name]) { + ALIASES[crate][alias_name].push(local_alias + currentIndex); + } + } + } + currentIndex += crateSize; + } + return searchWords; + } + + /** + * Callback for when the search form is submitted. + * @param {Event} [e] - The event that triggered this call, if any + */ + function onSearchSubmit(e) { + e.preventDefault(); + searchState.clearInputTimeout(); + search(); + } + + function putBackSearch() { + const search_input = searchState.input; + if (!searchState.input) { + return; + } + if (search_input.value !== "" && !searchState.isDisplayed()) { + searchState.showResults(); + if (browserSupportsHistoryApi()) { + history.replaceState(null, "", + buildUrl(search_input.value, getFilterCrates())); + } + document.title = searchState.title; + } + } + + function registerSearchEvents() { + const params = searchState.getQueryStringParams(); + + // Populate search bar with query string search term when provided, + // but only if the input bar is empty. This avoid the obnoxious issue + // where you start trying to do a search, and the index loads, and + // suddenly your search is gone! + if (searchState.input.value === "") { + searchState.input.value = params.search || ""; + } + + const searchAfter500ms = () => { + searchState.clearInputTimeout(); + if (searchState.input.value.length === 0) { + if (browserSupportsHistoryApi()) { + history.replaceState(null, window.currentCrate + " - Rust", + getNakedUrl() + window.location.hash); + } + searchState.hideResults(); + } else { + searchState.timeout = setTimeout(search, 500); + } + }; + searchState.input.onkeyup = searchAfter500ms; + searchState.input.oninput = searchAfter500ms; + document.getElementsByClassName("search-form")[0].onsubmit = onSearchSubmit; + searchState.input.onchange = e => { + if (e.target !== document.activeElement) { + // To prevent doing anything when it's from a blur event. + return; + } + // Do NOT e.preventDefault() here. It will prevent pasting. + searchState.clearInputTimeout(); + // zero-timeout necessary here because at the time of event handler execution the + // pasted content is not in the input field yet. Shouldn’t make any difference for + // change, though. + setTimeout(search, 0); + }; + searchState.input.onpaste = searchState.input.onchange; + + searchState.outputElement().addEventListener("keydown", e => { + // We only handle unmodified keystrokes here. We don't want to interfere with, + // for instance, alt-left and alt-right for history navigation. + if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { + return; + } + // up and down arrow select next/previous search result, or the + // search box if we're already at the top. + if (e.which === 38) { // up + const previous = document.activeElement.previousElementSibling; + if (previous) { + previous.focus(); + } else { + searchState.focus(); + } + e.preventDefault(); + } else if (e.which === 40) { // down + const next = document.activeElement.nextElementSibling; + if (next) { + next.focus(); + } + const rect = document.activeElement.getBoundingClientRect(); + if (window.innerHeight - rect.bottom < rect.height) { + window.scrollBy(0, rect.height); + } + e.preventDefault(); + } else if (e.which === 37) { // left + nextTab(-1); + e.preventDefault(); + } else if (e.which === 39) { // right + nextTab(1); + e.preventDefault(); + } + }); + + searchState.input.addEventListener("keydown", e => { + if (e.which === 40) { // down + focusSearchResult(); + e.preventDefault(); + } + }); + + searchState.input.addEventListener("focus", () => { + putBackSearch(); + }); + + searchState.input.addEventListener("blur", () => { + searchState.input.placeholder = searchState.input.origPlaceholder; + }); + + // Push and pop states are used to add search results to the browser + // history. + if (browserSupportsHistoryApi()) { + // Store the previous so we can revert back to it later. + const previousTitle = document.title; + + window.addEventListener("popstate", e => { + const params = searchState.getQueryStringParams(); + // Revert to the previous title manually since the History + // API ignores the title parameter. + document.title = previousTitle; + // When browsing forward to search results the previous + // search will be repeated, so the currentResults are + // cleared to ensure the search is successful. + currentResults = null; + // Synchronize search bar with query string state and + // perform the search. This will empty the bar if there's + // nothing there, which lets you really go back to a + // previous state with nothing in the bar. + if (params.search && params.search.length > 0) { + searchState.input.value = params.search; + // Some browsers fire "onpopstate" for every page load + // (Chrome), while others fire the event only when actually + // popping a state (Firefox), which is why search() is + // called both here and at the end of the startSearch() + // function. + search(e); + } else { + searchState.input.value = ""; + // When browsing back from search results the main page + // visibility must be reset. + searchState.hideResults(); + } + }); + } + + // This is required in firefox to avoid this problem: Navigating to a search result + // with the keyboard, hitting enter, and then hitting back would take you back to + // the doc page, rather than the search that should overlay it. + // This was an interaction between the back-forward cache and our handlers + // that try to sync state between the URL and the search input. To work around it, + // do a small amount of re-init on page show. + window.onpageshow = () => { + const qSearch = searchState.getQueryStringParams().search; + if (searchState.input.value === "" && qSearch) { + searchState.input.value = qSearch; + } + search(); + }; + } + + function updateCrate(ev) { + if (ev.target.value === "all crates") { + // If we don't remove it from the URL, it'll be picked up again by the search. + const params = searchState.getQueryStringParams(); + const query = searchState.input.value.trim(); + if (!history.state && !params.search) { + history.pushState(null, "", buildUrl(query, null)); + } else { + history.replaceState(null, "", buildUrl(query, null)); + } + } + // In case you "cut" the entry from the search input, then change the crate filter + // before paste back the previous search, you get the old search results without + // the filter. To prevent this, we need to remove the previous results. + currentResults = null; + search(undefined, true); + } + + /** + * @type {Array<string>} + */ + const searchWords = buildIndex(rawSearchIndex); + if (typeof window !== "undefined") { + registerSearchEvents(); + // If there's a search term in the URL, execute the search now. + if (window.searchState.getQueryStringParams().search) { + search(); + } + } + + if (typeof exports !== "undefined") { + exports.initSearch = initSearch; + exports.execQuery = execQuery; + exports.parseQuery = parseQuery; + } + return searchWords; +} + +if (typeof window !== "undefined") { + window.initSearch = initSearch; + if (window.searchIndex !== undefined) { + initSearch(window.searchIndex); + } +} else { + // Running in Node, not a browser. Run initSearch just to produce the + // exports. + initSearch({}); +} + + +})(); diff --git a/static.files/settings-3a0b9947ba1bd99a.js b/static.files/settings-3a0b9947ba1bd99a.js new file mode 100644 index 000000000..141563bd4 --- /dev/null +++ b/static.files/settings-3a0b9947ba1bd99a.js @@ -0,0 +1,283 @@ +// Local js definitions: +/* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */ +/* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */ +/* global MAIN_ID, getVar, getSettingsButton */ + +"use strict"; + +(function() { + const isSettingsPage = window.location.pathname.endsWith("/settings.html"); + + function changeSetting(settingName, value) { + updateLocalStorage(settingName, value); + + switch (settingName) { + case "theme": + case "preferred-dark-theme": + case "preferred-light-theme": + case "use-system-theme": + updateSystemTheme(); + updateLightAndDark(); + break; + case "line-numbers": + if (value === true) { + window.rustdoc_add_line_numbers_to_examples(); + } else { + window.rustdoc_remove_line_numbers_from_examples(); + } + break; + } + } + + function handleKey(ev) { + // Don't interfere with browser shortcuts + if (ev.ctrlKey || ev.altKey || ev.metaKey) { + return; + } + switch (getVirtualKey(ev)) { + case "Enter": + case "Return": + case "Space": + ev.target.checked = !ev.target.checked; + ev.preventDefault(); + break; + } + } + + function showLightAndDark() { + addClass(document.getElementById("theme").parentElement, "hidden"); + removeClass(document.getElementById("preferred-light-theme").parentElement, "hidden"); + removeClass(document.getElementById("preferred-dark-theme").parentElement, "hidden"); + } + + function hideLightAndDark() { + addClass(document.getElementById("preferred-light-theme").parentElement, "hidden"); + addClass(document.getElementById("preferred-dark-theme").parentElement, "hidden"); + removeClass(document.getElementById("theme").parentElement, "hidden"); + } + + function updateLightAndDark() { + if (getSettingValue("use-system-theme") !== "false") { + showLightAndDark(); + } else { + hideLightAndDark(); + } + } + + function setEvents(settingsElement) { + updateLightAndDark(); + onEachLazy(settingsElement.getElementsByClassName("slider"), elem => { + const toggle = elem.previousElementSibling; + const settingId = toggle.id; + const settingValue = getSettingValue(settingId); + if (settingValue !== null) { + toggle.checked = settingValue === "true"; + } + toggle.onchange = function() { + changeSetting(this.id, this.checked); + }; + toggle.onkeyup = handleKey; + toggle.onkeyrelease = handleKey; + }); + onEachLazy(settingsElement.getElementsByClassName("select-wrapper"), elem => { + const select = elem.getElementsByTagName("select")[0]; + const settingId = select.id; + const settingValue = getSettingValue(settingId); + if (settingValue !== null) { + select.value = settingValue; + } + select.onchange = function() { + changeSetting(this.id, this.value); + }; + }); + onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => { + const settingId = elem.name; + const settingValue = getSettingValue(settingId); + if (settingValue !== null && settingValue !== "null") { + elem.checked = settingValue === elem.value; + } + elem.addEventListener("change", ev => { + changeSetting(ev.target.name, ev.target.value); + }); + }); + } + + /** + * This function builds the sections inside the "settings page". It takes a `settings` list + * as argument which describes each setting and how to render it. It returns a string + * representing the raw HTML. + * + * @param {Array<Object>} settings + * + * @return {string} + */ + function buildSettingsPageSections(settings) { + let output = ""; + + for (const setting of settings) { + output += "<div class=\"setting-line\">"; + const js_data_name = setting["js_name"]; + const setting_name = setting["name"]; + + if (setting["options"] !== undefined) { + // This is a select setting. + output += `<div class="radio-line" id="${js_data_name}">\ + <span class="setting-name">${setting_name}</span>\ + <div class="choices">`; + onEach(setting["options"], option => { + const checked = option === setting["default"] ? " checked" : ""; + + output += `<label for="${js_data_name}-${option}" class="choice">\ + <input type="radio" name="${js_data_name}" \ + id="${js_data_name}-${option}" value="${option}"${checked}>\ + <span>${option}</span>\ + </label>`; + }); + output += "</div></div>"; + } else { + // This is a toggle. + const checked = setting["default"] === true ? " checked" : ""; + output += `<label class="toggle">\ + <input type="checkbox" id="${js_data_name}"${checked}>\ + <span class="slider"></span>\ + <span class="label">${setting_name}</span>\ + </label>`; + } + output += "</div>"; + } + return output; + } + + /** + * This function builds the "settings page" and returns the generated HTML element. + * + * @return {HTMLElement} + */ + function buildSettingsPage() { + const theme_names = getVar("themes").split(",").filter(t => t); + theme_names.push("light", "dark", "ayu"); + + const settings = [ + { + "name": "Use system theme", + "js_name": "use-system-theme", + "default": true, + }, + { + "name": "Theme", + "js_name": "theme", + "default": "light", + "options": theme_names, + }, + { + "name": "Preferred light theme", + "js_name": "preferred-light-theme", + "default": "light", + "options": theme_names, + }, + { + "name": "Preferred dark theme", + "js_name": "preferred-dark-theme", + "default": "dark", + "options": theme_names, + }, + { + "name": "Auto-hide item contents for large items", + "js_name": "auto-hide-large-items", + "default": true, + }, + { + "name": "Auto-hide item methods' documentation", + "js_name": "auto-hide-method-docs", + "default": false, + }, + { + "name": "Auto-hide trait implementation documentation", + "js_name": "auto-hide-trait-implementations", + "default": false, + }, + { + "name": "Directly go to item in search if there is only one result", + "js_name": "go-to-only-result", + "default": false, + }, + { + "name": "Show line numbers on code examples", + "js_name": "line-numbers", + "default": false, + }, + { + "name": "Disable keyboard shortcuts", + "js_name": "disable-shortcuts", + "default": false, + }, + ]; + + // Then we build the DOM. + const elementKind = isSettingsPage ? "section" : "div"; + const innerHTML = `<div class="settings">${buildSettingsPageSections(settings)}</div>`; + const el = document.createElement(elementKind); + el.id = "settings"; + if (!isSettingsPage) { + el.className = "popover"; + } + el.innerHTML = innerHTML; + + if (isSettingsPage) { + document.getElementById(MAIN_ID).appendChild(el); + } else { + el.setAttribute("tabindex", "-1"); + getSettingsButton().appendChild(el); + } + return el; + } + + const settingsMenu = buildSettingsPage(); + + function displaySettings() { + settingsMenu.style.display = ""; + } + + function settingsBlurHandler(event) { + blurHandler(event, getSettingsButton(), window.hidePopoverMenus); + } + + if (isSettingsPage) { + // We replace the existing "onclick" callback to do nothing if clicked. + getSettingsButton().onclick = function(event) { + event.preventDefault(); + }; + } else { + // We replace the existing "onclick" callback. + const settingsButton = getSettingsButton(); + const settingsMenu = document.getElementById("settings"); + settingsButton.onclick = function(event) { + if (elemIsInParent(event.target, settingsMenu)) { + return; + } + event.preventDefault(); + const shouldDisplaySettings = settingsMenu.style.display === "none"; + + window.hidePopoverMenus(); + if (shouldDisplaySettings) { + displaySettings(); + } + }; + settingsButton.onblur = settingsBlurHandler; + settingsButton.querySelector("a").onblur = settingsBlurHandler; + onEachLazy(settingsMenu.querySelectorAll("input"), el => { + el.onblur = settingsBlurHandler; + }); + settingsMenu.onblur = settingsBlurHandler; + } + + // We now wait a bit for the web browser to end re-computing the DOM... + setTimeout(() => { + setEvents(settingsMenu); + // The setting menu is already displayed if we're on the settings page. + if (!isSettingsPage) { + displaySettings(); + } + removeClass(getSettingsButton(), "rotate"); + }, 0); +})(); diff --git a/static.files/settings-a66f7524084a489a.css b/static.files/settings-a66f7524084a489a.css new file mode 100644 index 000000000..83939f63b --- /dev/null +++ b/static.files/settings-a66f7524084a489a.css @@ -0,0 +1,110 @@ +.setting-line { + margin: 0.6em 0 0.6em 0.3em; + position: relative; +} + +.setting-line .choices { + display: flex; + flex-wrap: wrap; +} + +.setting-line .radio-line input { + margin-right: 0.3em; + height: 1.2rem; + width: 1.2rem; + color: inherit; + border: 1px solid currentColor; + outline: none; + -webkit-appearance: none; + cursor: pointer; + border-radius: 50%; +} +.setting-line .radio-line input + span { + padding-bottom: 1px; +} + +.radio-line .setting-name { + width: 100%; +} + +.radio-line .choice { + margin-top: 0.1em; + margin-bottom: 0.1em; + min-width: 3.8em; + padding: 0.3em; + display: flex; + align-items: center; + cursor: pointer; +} +.radio-line .choice + .choice { + margin-left: 0.5em; +} + +.toggle { + position: relative; + width: 100%; + margin-right: 20px; + display: flex; + align-items: center; + cursor: pointer; +} + +.toggle input { + opacity: 0; + position: absolute; +} + +.slider { + position: relative; + width: 45px; + min-width: 45px; + display: block; + height: 28px; + margin-right: 20px; + cursor: pointer; + background-color: #ccc; + transition: .3s; +} + +.slider:before { + position: absolute; + content: ""; + height: 19px; + width: 19px; + left: 4px; + bottom: 4px; + transition: .3s; +} + +input:checked + .slider:before { + transform: translateX(19px); +} + +.setting-line > .sub-settings { + padding-left: 42px; + width: 100%; + display: block; +} + +#settings .setting-line { + margin: 1.2em 0.6em; +} + +.setting-line .radio-line input:checked { + box-shadow: inset 0 0 0 3px var(--main-background-color); + background-color: var(--settings-input-color); +} +.setting-line .radio-line input:focus { + box-shadow: 0 0 1px 1px var(--settings-input-color); +} +/* In here we combine both `:focus` and `:checked` properties. */ +.setting-line .radio-line input:checked:focus { + box-shadow: inset 0 0 0 3px var(--main-background-color), + 0 0 2px 2px var(--settings-input-color); +} +.setting-line .radio-line input:hover { + border-color: var(--settings-input-color) !important; +} +input:checked + .slider { + background-color: var(--settings-input-color); +} diff --git a/static.files/source-script-74087aa2e88f4475.js b/static.files/source-script-74087aa2e88f4475.js new file mode 100644 index 000000000..0b9368dd8 --- /dev/null +++ b/static.files/source-script-74087aa2e88f4475.js @@ -0,0 +1,228 @@ +// From rust: +/* global sourcesIndex */ + +// Local js definitions: +/* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */ +/* global updateLocalStorage */ + +"use strict"; + +(function() { + +const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; + +const NAME_OFFSET = 0; +const DIRS_OFFSET = 1; +const FILES_OFFSET = 2; + +function closeSidebarIfMobile() { + if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) { + updateLocalStorage("source-sidebar-show", "false"); + } +} + +function createDirEntry(elem, parent, fullPath, hasFoundFile) { + const dirEntry = document.createElement("details"); + const summary = document.createElement("summary"); + + dirEntry.className = "dir-entry"; + + fullPath += elem[NAME_OFFSET] + "/"; + + summary.innerText = elem[NAME_OFFSET]; + dirEntry.appendChild(summary); + + const folders = document.createElement("div"); + folders.className = "folders"; + if (elem[DIRS_OFFSET]) { + for (const dir of elem[DIRS_OFFSET]) { + if (createDirEntry(dir, folders, fullPath, false)) { + dirEntry.open = true; + hasFoundFile = true; + } + } + } + dirEntry.appendChild(folders); + + const files = document.createElement("div"); + files.className = "files"; + if (elem[FILES_OFFSET]) { + for (const file_text of elem[FILES_OFFSET]) { + const file = document.createElement("a"); + file.innerText = file_text; + file.href = rootPath + "src/" + fullPath + file_text + ".html"; + file.addEventListener("click", closeSidebarIfMobile); + const w = window.location.href.split("#")[0]; + if (!hasFoundFile && w === file.href) { + file.className = "selected"; + dirEntry.open = true; + hasFoundFile = true; + } + files.appendChild(file); + } + } + dirEntry.appendChild(files); + parent.appendChild(dirEntry); + return hasFoundFile; +} + +function toggleSidebar() { + const child = this.parentNode.children[0]; + if (child.innerText === ">") { + window.rustdocMobileScrollLock(); + addClass(document.documentElement, "source-sidebar-expanded"); + child.innerText = "<"; + updateLocalStorage("source-sidebar-show", "true"); + } else { + window.rustdocMobileScrollUnlock(); + removeClass(document.documentElement, "source-sidebar-expanded"); + child.innerText = ">"; + updateLocalStorage("source-sidebar-show", "false"); + } +} + +function createSidebarToggle() { + const sidebarToggle = document.createElement("div"); + sidebarToggle.id = "sidebar-toggle"; + + const inner = document.createElement("button"); + + if (getCurrentValue("source-sidebar-show") === "true") { + inner.innerText = "<"; + } else { + inner.innerText = ">"; + } + inner.onclick = toggleSidebar; + + sidebarToggle.appendChild(inner); + return sidebarToggle; +} + +// This function is called from "source-files.js", generated in `html/render/write_shared.rs`. +// eslint-disable-next-line no-unused-vars +function createSourceSidebar() { + const container = document.querySelector("nav.sidebar"); + + const sidebarToggle = createSidebarToggle(); + container.insertBefore(sidebarToggle, container.firstChild); + + const sidebar = document.createElement("div"); + sidebar.id = "source-sidebar"; + + let hasFoundFile = false; + + const title = document.createElement("div"); + title.className = "title"; + title.innerText = "Files"; + sidebar.appendChild(title); + Object.keys(sourcesIndex).forEach(key => { + sourcesIndex[key][NAME_OFFSET] = key; + hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", + hasFoundFile); + }); + + container.appendChild(sidebar); + // Focus on the current file in the source files sidebar. + const selected_elem = sidebar.getElementsByClassName("selected")[0]; + if (typeof selected_elem !== "undefined") { + selected_elem.focus(); + } +} + +const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; + +function highlightSourceLines(match) { + if (typeof match === "undefined") { + match = window.location.hash.match(lineNumbersRegex); + } + if (!match) { + return; + } + let from = parseInt(match[1], 10); + let to = from; + if (typeof match[2] !== "undefined") { + to = parseInt(match[2], 10); + } + if (to < from) { + const tmp = to; + to = from; + from = tmp; + } + let elem = document.getElementById(from); + if (!elem) { + return; + } + const x = document.getElementById(from); + if (x) { + x.scrollIntoView(); + } + onEachLazy(document.getElementsByClassName("src-line-numbers"), e => { + onEachLazy(e.getElementsByTagName("span"), i_e => { + removeClass(i_e, "line-highlighted"); + }); + }); + for (let i = from; i <= to; ++i) { + elem = document.getElementById(i); + if (!elem) { + break; + } + addClass(elem, "line-highlighted"); + } +} + +const handleSourceHighlight = (function() { + let prev_line_id = 0; + + const set_fragment = name => { + const x = window.scrollX, + y = window.scrollY; + if (browserSupportsHistoryApi()) { + history.replaceState(null, null, "#" + name); + highlightSourceLines(); + } else { + location.replace("#" + name); + } + // Prevent jumps when selecting one or many lines + window.scrollTo(x, y); + }; + + return ev => { + let cur_line_id = parseInt(ev.target.id, 10); + // It can happen when clicking not on a line number span. + if (isNaN(cur_line_id)) { + return; + } + ev.preventDefault(); + + if (ev.shiftKey && prev_line_id) { + // Swap selection if needed + if (prev_line_id > cur_line_id) { + const tmp = prev_line_id; + prev_line_id = cur_line_id; + cur_line_id = tmp; + } + + set_fragment(prev_line_id + "-" + cur_line_id); + } else { + prev_line_id = cur_line_id; + + set_fragment(cur_line_id); + } + }; +}()); + +window.addEventListener("hashchange", () => { + const match = window.location.hash.match(lineNumbersRegex); + if (match) { + return highlightSourceLines(match); + } +}); + +onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { + el.addEventListener("click", handleSourceHighlight); +}); + +highlightSourceLines(); + +window.createSourceSidebar = createSourceSidebar; +})(); diff --git a/static.files/storage-d43fa987303ecbbb.js b/static.files/storage-d43fa987303ecbbb.js new file mode 100644 index 000000000..db2db83ca --- /dev/null +++ b/static.files/storage-d43fa987303ecbbb.js @@ -0,0 +1,264 @@ +// storage.js is loaded in the `<head>` of all rustdoc pages and doesn't +// use `async` or `defer`. That means it blocks further parsing and rendering +// of the page: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script. +// This makes it the correct place to act on settings that affect the display of +// the page, so we don't see major layout changes during the load of the page. +"use strict"; + +const darkThemes = ["dark", "ayu"]; +window.currentTheme = document.getElementById("themeStyle"); +window.mainTheme = document.getElementById("mainThemeStyle"); + +// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY +// If you update this line, then you also need to update the media query with the same +// warning in rustdoc.css +window.RUSTDOC_MOBILE_BREAKPOINT = 700; + +const settingsDataset = (function() { + const settingsElement = document.getElementById("default-settings"); + if (settingsElement === null) { + return null; + } + const dataset = settingsElement.dataset; + if (dataset === undefined) { + return null; + } + return dataset; +})(); + +function getSettingValue(settingName) { + const current = getCurrentValue(settingName); + if (current !== null) { + return current; + } + if (settingsDataset !== null) { + // See the comment for `default_settings.into_iter()` etc. in + // `Options::from_matches` in `librustdoc/config.rs`. + const def = settingsDataset[settingName.replace(/-/g,"_")]; + if (def !== undefined) { + return def; + } + } + return null; +} + +const localStoredTheme = getSettingValue("theme"); + +const savedHref = []; + +// eslint-disable-next-line no-unused-vars +function hasClass(elem, className) { + return elem && elem.classList && elem.classList.contains(className); +} + +// eslint-disable-next-line no-unused-vars +function addClass(elem, className) { + if (!elem || !elem.classList) { + return; + } + elem.classList.add(className); +} + +// eslint-disable-next-line no-unused-vars +function removeClass(elem, className) { + if (!elem || !elem.classList) { + return; + } + elem.classList.remove(className); +} + +/** + * Run a callback for every element of an Array. + * @param {Array<?>} arr - The array to iterate over + * @param {function(?)} func - The callback + * @param {boolean} [reversed] - Whether to iterate in reverse + */ +function onEach(arr, func, reversed) { + if (arr && arr.length > 0 && func) { + if (reversed) { + const length = arr.length; + for (let i = length - 1; i >= 0; --i) { + if (func(arr[i])) { + return true; + } + } + } else { + for (const elem of arr) { + if (func(elem)) { + return true; + } + } + } + } + return false; +} + +/** + * Turn an HTMLCollection or a NodeList into an Array, then run a callback + * for every element. This is useful because iterating over an HTMLCollection + * or a "live" NodeList while modifying it can be very slow. + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection + * https://developer.mozilla.org/en-US/docs/Web/API/NodeList + * @param {NodeList<?>|HTMLCollection<?>} lazyArray - An array to iterate over + * @param {function(?)} func - The callback + * @param {boolean} [reversed] - Whether to iterate in reverse + */ +function onEachLazy(lazyArray, func, reversed) { + return onEach( + Array.prototype.slice.call(lazyArray), + func, + reversed); +} + +function updateLocalStorage(name, value) { + try { + window.localStorage.setItem("rustdoc-" + name, value); + } catch (e) { + // localStorage is not accessible, do nothing + } +} + +function getCurrentValue(name) { + try { + return window.localStorage.getItem("rustdoc-" + name); + } catch (e) { + return null; + } +} + +function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) { + // If this new value comes from a system setting or from the previously + // saved theme, no need to save it. + if (saveTheme) { + updateLocalStorage("theme", newThemeName); + } + + if (savedHref.length === 0) { + onEachLazy(document.getElementsByTagName("link"), el => { + savedHref.push(el.href); + }); + } + const newHref = savedHref.find(url => { + const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/); + if (m && m[1] === newThemeName) { + return true; + } + const m2 = url.match(/\/([^/]*)\.css$/); + if (m2 && m2[1].startsWith(newThemeName)) { + return true; + } + }); + if (newHref && newHref !== styleElem.href) { + styleElem.href = newHref; + } +} + +// This function is called from "main.js". +// eslint-disable-next-line no-unused-vars +function useSystemTheme(value) { + if (value === undefined) { + value = true; + } + + updateLocalStorage("use-system-theme", value); + + // update the toggle if we're on the settings page + const toggle = document.getElementById("use-system-theme"); + if (toggle && toggle instanceof HTMLInputElement) { + toggle.checked = value; + } +} + +const updateSystemTheme = (function() { + if (!window.matchMedia) { + // fallback to the CSS computed value + return () => { + const cssTheme = getComputedStyle(document.documentElement) + .getPropertyValue("content"); + + switchTheme( + window.currentTheme, + window.mainTheme, + JSON.parse(cssTheme) || "light", + true + ); + }; + } + + // only listen to (prefers-color-scheme: dark) because light is the default + const mql = window.matchMedia("(prefers-color-scheme: dark)"); + + function handlePreferenceChange(mql) { + const use = theme => { + switchTheme(window.currentTheme, window.mainTheme, theme, true); + }; + // maybe the user has disabled the setting in the meantime! + if (getSettingValue("use-system-theme") !== "false") { + const lightTheme = getSettingValue("preferred-light-theme") || "light"; + const darkTheme = getSettingValue("preferred-dark-theme") || "dark"; + + if (mql.matches) { + use(darkTheme); + } else { + // prefers a light theme, or has no preference + use(lightTheme); + } + // note: we save the theme so that it doesn't suddenly change when + // the user disables "use-system-theme" and reloads the page or + // navigates to another page + } else { + use(getSettingValue("theme")); + } + } + + mql.addListener(handlePreferenceChange); + + return () => { + handlePreferenceChange(mql); + }; +})(); + +function switchToSavedTheme() { + switchTheme( + window.currentTheme, + window.mainTheme, + getSettingValue("theme") || "light", + false + ); +} + +if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { + // update the preferred dark theme if the user is already using a dark theme + // See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732 + if (getSettingValue("use-system-theme") === null + && getSettingValue("preferred-dark-theme") === null + && darkThemes.indexOf(localStoredTheme) >= 0) { + updateLocalStorage("preferred-dark-theme", localStoredTheme); + } + + // call the function to initialize the theme at least once! + updateSystemTheme(); +} else { + switchToSavedTheme(); +} + +if (getSettingValue("source-sidebar-show") === "true") { + // At this point in page load, `document.body` is not available yet. + // Set a class on the `<html>` element instead. + addClass(document.documentElement, "source-sidebar-expanded"); +} + +// If we navigate away (for example to a settings page), and then use the back or +// forward button to get back to a page, the theme may have changed in the meantime. +// But scripts may not be re-loaded in such a case due to the bfcache +// (https://web.dev/bfcache/). The "pageshow" event triggers on such navigations. +// Use that opportunity to update the theme. +// We use a setTimeout with a 0 timeout here to put the change on the event queue. +// For some reason, if we try to change the theme while the `pageshow` event is +// running, it sometimes fails to take effect. The problem manifests on Chrome, +// specifically when talking to a remote website with no caching. +window.addEventListener("pageshow", ev => { + if (ev.persisted) { + setTimeout(switchToSavedTheme, 0); + } +}); diff --git a/static.files/toggle-minus-31bbd6e4c77f5c96.svg b/static.files/toggle-minus-31bbd6e4c77f5c96.svg new file mode 100644 index 000000000..73154788a --- /dev/null +++ b/static.files/toggle-minus-31bbd6e4c77f5c96.svg @@ -0,0 +1 @@ +<svg width="17" height="17" shape-rendering="crispEdges" stroke="#000" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 2.5H2.5v12H5m7-12h2.5v12H12M5 8.5h7"/></svg> \ No newline at end of file diff --git a/static.files/toggle-plus-1092eb4930d581b0.svg b/static.files/toggle-plus-1092eb4930d581b0.svg new file mode 100644 index 000000000..08b17033e --- /dev/null +++ b/static.files/toggle-plus-1092eb4930d581b0.svg @@ -0,0 +1 @@ +<svg width="17" height="17" shape-rendering="crispEdges" stroke="#000" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5 2.5H2.5v12H5m7-12h2.5v12H12M5 8.5h7M8.5 12V8.625v0V5"/></svg> \ No newline at end of file diff --git a/static.files/wheel-5ec35bf9ca753509.svg b/static.files/wheel-5ec35bf9ca753509.svg new file mode 100644 index 000000000..01da3b24c --- /dev/null +++ b/static.files/wheel-5ec35bf9ca753509.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Capa_1" width="27.434" height="29.5" enable-background="new 0 0 27.434 29.5" version="1.1" viewBox="0 0 27.434 29.5" xml:space="preserve"><g><path d="M27.315,18.389c-0.165-0.604-0.509-1.113-0.981-1.459c-0.042-0.144-0.083-0.429-0.015-0.761l0.037-0.177v-0.182V14.8 c0-1.247-0.006-1.277-0.048-1.472c-0.076-0.354-0.035-0.653,0.007-0.803c0.477-0.346,0.828-0.861,0.996-1.476 c0.261-0.956,0.076-2.091-0.508-3.114l-0.591-1.032c-0.746-1.307-1.965-2.119-3.182-2.119c-0.378,0-0.75,0.081-1.085,0.235 c-0.198-0.025-0.554-0.15-0.855-0.389l-0.103-0.082l-0.114-0.065l-1.857-1.067L18.92,3.36l-0.105-0.044 c-0.376-0.154-0.658-0.41-0.768-0.556C17.918,1.172,16.349,0,14.296,0H13.14c-2.043,0-3.608,1.154-3.749,2.721 C9.277,2.862,8.999,3.104,8.633,3.25l-0.1,0.039L8.439,3.341L6.495,4.406L6.363,4.479L6.245,4.573 C5.936,4.82,5.596,4.944,5.416,4.977c-0.314-0.139-0.66-0.21-1.011-0.21c-1.198,0-2.411,0.819-3.165,2.139L0.65,7.938 c-0.412,0.72-0.642,1.521-0.644,2.258c-0.003,0.952,0.362,1.756,1.013,2.256c0.034,0.155,0.061,0.448-0.016,0.786 c-0.038,0.168-0.062,0.28-0.062,1.563c0,1.148,0,1.148,0.015,1.262l0.009,0.073l0.017,0.073c0.073,0.346,0.045,0.643,0.011,0.802 C0.348,17.512-0.01,18.314,0,19.268c0.008,0.729,0.238,1.523,0.648,2.242l0.589,1.031c0.761,1.331,1.967,2.159,3.15,2.159 c0.324,0,0.645-0.064,0.938-0.187c0.167,0.038,0.492,0.156,0.813,0.416l0.11,0.088l0.124,0.07l2.045,1.156l0.102,0.057l0.107,0.043 c0.364,0.147,0.646,0.381,0.766,0.521c0.164,1.52,1.719,2.634,3.745,2.634h1.155c2.037,0,3.598-1.134,3.747-2.675 c0.117-0.145,0.401-0.393,0.774-0.549l0.111-0.047l0.105-0.062l1.96-1.159l0.105-0.062l0.097-0.075 c0.309-0.246,0.651-0.371,0.832-0.402c0.313,0.138,0.662,0.212,1.016,0.212c1.199,0,2.412-0.82,3.166-2.139l0.59-1.032 C27.387,20.48,27.575,19.342,27.315,18.389z M25.274,20.635l-0.59,1.032c-0.438,0.765-1.104,1.251-1.639,1.251 c-0.133,0-0.258-0.029-0.369-0.094c-0.15-0.086-0.346-0.127-0.566-0.127c-0.596,0-1.383,0.295-2.01,0.796l-1.96,1.157 c-1.016,0.425-1.846,1.291-1.846,1.929s-0.898,1.159-1.998,1.159H13.14c-1.1,0-1.998-0.514-1.998-1.141s-0.834-1.477-1.854-1.888 l-2.046-1.157c-0.636-0.511-1.425-0.814-2.006-0.814c-0.202,0-0.379,0.037-0.516,0.115c-0.101,0.057-0.214,0.084-0.333,0.084 c-0.518,0-1.179-0.498-1.62-1.271l-0.591-1.032c-0.545-0.954-0.556-1.983-0.024-2.286c0.532-0.305,0.78-1.432,0.551-2.506 c0,0,0-0.003,0-1.042c0-1.088,0.021-1.18,0.021-1.18c0.238-1.072-0.01-2.203-0.552-2.513C1.631,10.8,1.634,9.765,2.18,8.812 L2.769,7.78c0.438-0.766,1.103-1.251,1.636-1.251c0.131,0,0.255,0.029,0.365,0.092C4.92,6.707,5.114,6.747,5.334,6.747 c0.596,0,1.38-0.296,2.007-0.795l1.944-1.065c1.021-0.407,1.856-1.277,1.856-1.933c0-0.656,0.898-1.192,1.998-1.192h1.156V1.761 c1.1,0,1.998,0.545,1.998,1.211c0,0.667,0.832,1.554,1.849,1.973L20,6.013c0.618,0.489,1.401,0.775,2.012,0.775 c0.24,0,0.454-0.045,0.62-0.139c0.122-0.069,0.259-0.102,0.403-0.102c0.551,0,1.221,0.476,1.653,1.231l0.59,1.032 c0.544,0.953,0.518,2.004-0.062,2.334c-0.577,0.331-0.859,1.48-0.627,2.554c0,0,0.01,0.042,0.01,1.103c0,1.012,0,1.012,0,1.012 c-0.218,1.049,0.068,2.174,0.636,2.498C25.802,18.635,25.819,19.68,25.274,20.635z"/><path d="M13.61,7.611c-3.913,0-7.084,3.173-7.084,7.085c0,3.914,3.171,7.085,7.084,7.085s7.085-3.172,7.085-7.085 C20.695,10.784,17.523,7.611,13.61,7.611z M13.61,20.02c-2.936,0-5.323-2.388-5.323-5.323c0-2.935,2.388-5.323,5.323-5.323 s5.324,2.388,5.324,5.323C18.934,17.632,16.546,20.02,13.61,20.02z"/><path d="M13.682,9.908c-2.602,0-4.718,2.116-4.718,4.718c0,2.601,2.116,4.716,4.718,4.716c2.601,0,4.717-2.115,4.717-4.716 C18.399,12.024,16.283,9.908,13.682,9.908z M13.682,17.581c-1.633,0-2.956-1.323-2.956-2.955s1.323-2.956,2.956-2.956 c1.632,0,2.956,1.324,2.956,2.956S15.314,17.581,13.682,17.581z"/></g></svg> \ No newline at end of file