summaryrefslogtreecommitdiffstats
path: root/third_party/rust/bytes/src/buf/ext
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/bytes/src/buf/ext
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/bytes/src/buf/ext')
-rw-r--r--third_party/rust/bytes/src/buf/ext/chain.rs234
-rw-r--r--third_party/rust/bytes/src/buf/ext/limit.rs77
-rw-r--r--third_party/rust/bytes/src/buf/ext/mod.rs176
-rw-r--r--third_party/rust/bytes/src/buf/ext/reader.rs81
-rw-r--r--third_party/rust/bytes/src/buf/ext/take.rs150
-rw-r--r--third_party/rust/bytes/src/buf/ext/writer.rs88
6 files changed, 806 insertions, 0 deletions
diff --git a/third_party/rust/bytes/src/buf/ext/chain.rs b/third_party/rust/bytes/src/buf/ext/chain.rs
new file mode 100644
index 0000000000..a1ec597df6
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/chain.rs
@@ -0,0 +1,234 @@
+use crate::{Buf, BufMut};
+use crate::buf::IntoIter;
+
+use core::mem::MaybeUninit;
+
+#[cfg(feature = "std")]
+use std::io::{IoSlice};
+#[cfg(feature = "std")]
+use crate::buf::IoSliceMut;
+
+/// A `Chain` sequences two buffers.
+///
+/// `Chain` is an adapter that links two underlying buffers and provides a
+/// continuous view across both buffers. It is able to sequence either immutable
+/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values).
+///
+/// This struct is generally created by calling [`Buf::chain`]. Please see that
+/// function's documentation for more detail.
+///
+/// # Examples
+///
+/// ```
+/// use bytes::{Bytes, Buf, buf::BufExt};
+///
+/// let mut buf = (&b"hello "[..])
+/// .chain(&b"world"[..]);
+///
+/// let full: Bytes = buf.to_bytes();
+/// assert_eq!(full[..], b"hello world"[..]);
+/// ```
+///
+/// [`Buf::chain`]: trait.Buf.html#method.chain
+/// [`Buf`]: trait.Buf.html
+/// [`BufMut`]: trait.BufMut.html
+#[derive(Debug)]
+pub struct Chain<T, U> {
+ a: T,
+ b: U,
+}
+
+impl<T, U> Chain<T, U> {
+ /// Creates a new `Chain` sequencing the provided values.
+ pub fn new(a: T, b: U) -> Chain<T, U> {
+ Chain {
+ a,
+ b,
+ }
+ }
+
+ /// Gets a reference to the first underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::buf::BufExt;
+ ///
+ /// let buf = (&b"hello"[..])
+ /// .chain(&b"world"[..]);
+ ///
+ /// assert_eq!(buf.first_ref()[..], b"hello"[..]);
+ /// ```
+ pub fn first_ref(&self) -> &T {
+ &self.a
+ }
+
+ /// Gets a mutable reference to the first underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{Buf, buf::BufExt};
+ ///
+ /// let mut buf = (&b"hello"[..])
+ /// .chain(&b"world"[..]);
+ ///
+ /// buf.first_mut().advance(1);
+ ///
+ /// let full = buf.to_bytes();
+ /// assert_eq!(full, b"elloworld"[..]);
+ /// ```
+ pub fn first_mut(&mut self) -> &mut T {
+ &mut self.a
+ }
+
+ /// Gets a reference to the last underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::buf::BufExt;
+ ///
+ /// let buf = (&b"hello"[..])
+ /// .chain(&b"world"[..]);
+ ///
+ /// assert_eq!(buf.last_ref()[..], b"world"[..]);
+ /// ```
+ pub fn last_ref(&self) -> &U {
+ &self.b
+ }
+
+ /// Gets a mutable reference to the last underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{Buf, buf::BufExt};
+ ///
+ /// let mut buf = (&b"hello "[..])
+ /// .chain(&b"world"[..]);
+ ///
+ /// buf.last_mut().advance(1);
+ ///
+ /// let full = buf.to_bytes();
+ /// assert_eq!(full, b"hello orld"[..]);
+ /// ```
+ pub fn last_mut(&mut self) -> &mut U {
+ &mut self.b
+ }
+
+ /// Consumes this `Chain`, returning the underlying values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::buf::BufExt;
+ ///
+ /// let chain = (&b"hello"[..])
+ /// .chain(&b"world"[..]);
+ ///
+ /// let (first, last) = chain.into_inner();
+ /// assert_eq!(first[..], b"hello"[..]);
+ /// assert_eq!(last[..], b"world"[..]);
+ /// ```
+ pub fn into_inner(self) -> (T, U) {
+ (self.a, self.b)
+ }
+}
+
+impl<T, U> Buf for Chain<T, U>
+ where T: Buf,
+ U: Buf,
+{
+ fn remaining(&self) -> usize {
+ self.a.remaining() + self.b.remaining()
+ }
+
+ fn bytes(&self) -> &[u8] {
+ if self.a.has_remaining() {
+ self.a.bytes()
+ } else {
+ self.b.bytes()
+ }
+ }
+
+ fn advance(&mut self, mut cnt: usize) {
+ let a_rem = self.a.remaining();
+
+ if a_rem != 0 {
+ if a_rem >= cnt {
+ self.a.advance(cnt);
+ return;
+ }
+
+ // Consume what is left of a
+ self.a.advance(a_rem);
+
+ cnt -= a_rem;
+ }
+
+ self.b.advance(cnt);
+ }
+
+ #[cfg(feature = "std")]
+ fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
+ let mut n = self.a.bytes_vectored(dst);
+ n += self.b.bytes_vectored(&mut dst[n..]);
+ n
+ }
+}
+
+impl<T, U> BufMut for Chain<T, U>
+ where T: BufMut,
+ U: BufMut,
+{
+ fn remaining_mut(&self) -> usize {
+ self.a.remaining_mut() + self.b.remaining_mut()
+ }
+
+ fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ if self.a.has_remaining_mut() {
+ self.a.bytes_mut()
+ } else {
+ self.b.bytes_mut()
+ }
+ }
+
+ unsafe fn advance_mut(&mut self, mut cnt: usize) {
+ let a_rem = self.a.remaining_mut();
+
+ if a_rem != 0 {
+ if a_rem >= cnt {
+ self.a.advance_mut(cnt);
+ return;
+ }
+
+ // Consume what is left of a
+ self.a.advance_mut(a_rem);
+
+ cnt -= a_rem;
+ }
+
+ self.b.advance_mut(cnt);
+ }
+
+ #[cfg(feature = "std")]
+ fn bytes_vectored_mut<'a>(&'a mut self, dst: &mut [IoSliceMut<'a>]) -> usize {
+ let mut n = self.a.bytes_vectored_mut(dst);
+ n += self.b.bytes_vectored_mut(&mut dst[n..]);
+ n
+ }
+}
+
+impl<T, U> IntoIterator for Chain<T, U>
+where
+ T: Buf,
+ U: Buf,
+{
+ type Item = u8;
+ type IntoIter = IntoIter<Chain<T, U>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ IntoIter::new(self)
+ }
+}
diff --git a/third_party/rust/bytes/src/buf/ext/limit.rs b/third_party/rust/bytes/src/buf/ext/limit.rs
new file mode 100644
index 0000000000..f86e01151c
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/limit.rs
@@ -0,0 +1,77 @@
+use crate::BufMut;
+
+use core::{cmp, mem::MaybeUninit};
+
+/// 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
+ }
+}
+
+impl<T: BufMut> BufMut for Limit<T> {
+ fn remaining_mut(&self) -> usize {
+ cmp::min(self.inner.remaining_mut(), self.limit)
+ }
+
+ fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
+ let bytes = self.inner.bytes_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;
+ }
+}
diff --git a/third_party/rust/bytes/src/buf/ext/mod.rs b/third_party/rust/bytes/src/buf/ext/mod.rs
new file mode 100644
index 0000000000..7b0bdab200
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/mod.rs
@@ -0,0 +1,176 @@
+//! Extra utilities for `Buf` and `BufMut` types.
+
+use super::{Buf, BufMut};
+
+mod chain;
+mod limit;
+#[cfg(feature = "std")]
+mod reader;
+mod take;
+#[cfg(feature = "std")]
+mod writer;
+
+pub use self::limit::Limit;
+pub use self::take::Take;
+pub use self::chain::Chain;
+
+#[cfg(feature = "std")]
+pub use self::{reader::Reader, writer::Writer};
+
+/// Extra methods for implementations of `Buf`.
+pub trait BufExt: Buf {
+ /// Creates an adaptor which will read at most `limit` bytes from `self`.
+ ///
+ /// This function returns a new instance of `Buf` which will read at most
+ /// `limit` bytes.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{Buf, BufMut, buf::BufExt};
+ ///
+ /// let mut buf = b"hello world"[..].take(5);
+ /// let mut dst = vec![];
+ ///
+ /// dst.put(&mut buf);
+ /// assert_eq!(dst, b"hello");
+ ///
+ /// let mut buf = buf.into_inner();
+ /// dst.clear();
+ /// dst.put(&mut buf);
+ /// assert_eq!(dst, b" world");
+ /// ```
+ fn take(self, limit: usize) -> Take<Self>
+ where Self: Sized
+ {
+ take::new(self, limit)
+ }
+
+ /// Creates an adaptor which will chain this buffer with another.
+ ///
+ /// The returned `Buf` instance will first consume all bytes from `self`.
+ /// Afterwards the output is equivalent to the output of next.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{Buf, buf::BufExt};
+ ///
+ /// let mut chain = b"hello "[..].chain(&b"world"[..]);
+ ///
+ /// let full = chain.to_bytes();
+ /// assert_eq!(full.bytes(), b"hello world");
+ /// ```
+ fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
+ where Self: Sized
+ {
+ Chain::new(self, next)
+ }
+
+ /// Creates an adaptor which implements the `Read` trait for `self`.
+ ///
+ /// This function returns a new value which implements `Read` by adapting
+ /// the `Read` trait functions to the `Buf` trait functions. Given that
+ /// `Buf` operations are infallible, none of the `Read` functions will
+ /// return with `Err`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{Buf, Bytes, buf::BufExt};
+ /// use std::io::Read;
+ ///
+ /// let buf = Bytes::from("hello world");
+ ///
+ /// let mut reader = buf.reader();
+ /// let mut dst = [0; 1024];
+ ///
+ /// let num = reader.read(&mut dst).unwrap();
+ ///
+ /// assert_eq!(11, num);
+ /// assert_eq!(&dst[..11], &b"hello world"[..]);
+ /// ```
+ #[cfg(feature = "std")]
+ fn reader(self) -> Reader<Self> where Self: Sized {
+ reader::new(self)
+ }
+}
+
+impl<B: Buf + ?Sized> BufExt for B {}
+
+/// Extra methods for implementations of `BufMut`.
+pub trait BufMutExt: BufMut {
+ /// Creates an adaptor which can write at most `limit` bytes to `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use bytes::{BufMut, buf::BufMutExt};
+ ///
+ /// let arr = &mut [0u8; 128][..];
+ /// assert_eq!(arr.remaining_mut(), 128);
+ ///
+ /// let dst = arr.limit(10);
+ /// assert_eq!(dst.remaining_mut(), 10);
+ /// ```
+ 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, buf::BufMutExt};
+ /// use std::io::Write;
+ ///
+ /// let mut buf = vec![].writer();
+ ///
+ /// let num = buf.write(&b"hello world"[..]).unwrap();
+ /// assert_eq!(11, num);
+ ///
+ /// let buf = buf.into_inner();
+ ///
+ /// assert_eq!(*buf, b"hello world"[..]);
+ /// ```
+ #[cfg(feature = "std")]
+ fn writer(self) -> Writer<Self> where Self: Sized {
+ writer::new(self)
+ }
+
+ /// 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, buf::BufMutExt};
+ ///
+ /// 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");
+ /// ```
+ fn chain_mut<U: BufMut>(self, next: U) -> Chain<Self, U>
+ where Self: Sized
+ {
+ Chain::new(self, next)
+ }
+}
+
+impl<B: BufMut + ?Sized> BufMutExt for B {}
diff --git a/third_party/rust/bytes/src/buf/ext/reader.rs b/third_party/rust/bytes/src/buf/ext/reader.rs
new file mode 100644
index 0000000000..e38103b1de
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/reader.rs
@@ -0,0 +1,81 @@
+use crate::{Buf};
+
+use std::{cmp, io};
+
+/// A `Buf` adapter which implements `io::Read` for the inner value.
+///
+/// This struct is generally created by calling `reader()` on `Buf`. See
+/// documentation of [`reader()`](trait.Buf.html#method.reader) for more
+/// details.
+#[derive(Debug)]
+pub struct Reader<B> {
+ buf: B,
+}
+
+pub fn new<B>(buf: B) -> Reader<B> {
+ Reader { buf }
+}
+
+impl<B: Buf> Reader<B> {
+ /// Gets a reference to the underlying `Buf`.
+ ///
+ /// It is inadvisable to directly read from the underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::buf::BufExt;
+ ///
+ /// let mut buf = b"hello world".reader();
+ ///
+ /// assert_eq!(b"hello world", buf.get_ref());
+ /// ```
+ pub fn get_ref(&self) -> &B {
+ &self.buf
+ }
+
+ /// Gets a mutable reference to the underlying `Buf`.
+ ///
+ /// It is inadvisable to directly read from the underlying `Buf`.
+ pub fn get_mut(&mut self) -> &mut B {
+ &mut self.buf
+ }
+
+ /// Consumes this `Reader`, returning the underlying value.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::{Buf, buf::BufExt};
+ /// use std::io;
+ ///
+ /// let mut buf = b"hello world".reader();
+ /// let mut dst = vec![];
+ ///
+ /// io::copy(&mut buf, &mut dst).unwrap();
+ ///
+ /// let buf = buf.into_inner();
+ /// assert_eq!(0, buf.remaining());
+ /// ```
+ pub fn into_inner(self) -> B {
+ self.buf
+ }
+}
+
+impl<B: Buf + Sized> io::Read for Reader<B> {
+ fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
+ let len = cmp::min(self.buf.remaining(), dst.len());
+
+ Buf::copy_to_slice(&mut self.buf, &mut dst[0..len]);
+ Ok(len)
+ }
+}
+
+impl<B: Buf + Sized> io::BufRead for Reader<B> {
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ Ok(self.buf.bytes())
+ }
+ fn consume(&mut self, amt: usize) {
+ self.buf.advance(amt)
+ }
+}
diff --git a/third_party/rust/bytes/src/buf/ext/take.rs b/third_party/rust/bytes/src/buf/ext/take.rs
new file mode 100644
index 0000000000..6fc4ffc72c
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/take.rs
@@ -0,0 +1,150 @@
+use crate::Buf;
+
+use core::cmp;
+
+/// A `Buf` adapter which limits the bytes read from an underlying buffer.
+///
+/// This struct is generally created by calling `take()` on `Buf`. See
+/// documentation of [`take()`](trait.Buf.html#method.take) for more details.
+#[derive(Debug)]
+pub struct Take<T> {
+ inner: T,
+ limit: usize,
+}
+
+pub fn new<T>(inner: T, limit: usize) -> Take<T> {
+ Take {
+ inner,
+ limit,
+ }
+}
+
+impl<T> Take<T> {
+ /// Consumes this `Take`, returning the underlying value.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::buf::{Buf, BufMut, BufExt};
+ ///
+ /// let mut buf = b"hello world".take(2);
+ /// let mut dst = vec![];
+ ///
+ /// dst.put(&mut buf);
+ /// assert_eq!(*dst, b"he"[..]);
+ ///
+ /// let mut buf = buf.into_inner();
+ ///
+ /// dst.clear();
+ /// dst.put(&mut buf);
+ /// assert_eq!(*dst, b"llo world"[..]);
+ /// ```
+ pub fn into_inner(self) -> T {
+ self.inner
+ }
+
+ /// Gets a reference to the underlying `Buf`.
+ ///
+ /// It is inadvisable to directly read from the underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::{Buf, buf::BufExt};
+ ///
+ /// let mut buf = b"hello world".take(2);
+ ///
+ /// assert_eq!(11, buf.get_ref().remaining());
+ /// ```
+ pub fn get_ref(&self) -> &T {
+ &self.inner
+ }
+
+ /// Gets a mutable reference to the underlying `Buf`.
+ ///
+ /// It is inadvisable to directly read from the underlying `Buf`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::{Buf, BufMut, buf::BufExt};
+ ///
+ /// let mut buf = b"hello world".take(2);
+ /// let mut dst = vec![];
+ ///
+ /// buf.get_mut().advance(2);
+ ///
+ /// dst.put(&mut buf);
+ /// assert_eq!(*dst, b"ll"[..]);
+ /// ```
+ pub fn get_mut(&mut self) -> &mut T {
+ &mut self.inner
+ }
+
+ /// Returns the maximum number of bytes that can be read.
+ ///
+ /// # Note
+ ///
+ /// If the inner `Buf` has fewer bytes than indicated by this method then
+ /// that is the actual number of available bytes.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::{Buf, buf::BufExt};
+ ///
+ /// let mut buf = b"hello world".take(2);
+ ///
+ /// assert_eq!(2, buf.limit());
+ /// assert_eq!(b'h', buf.get_u8());
+ /// assert_eq!(1, buf.limit());
+ /// ```
+ pub fn limit(&self) -> usize {
+ self.limit
+ }
+
+ /// Sets the maximum number of bytes that can be read.
+ ///
+ /// # Note
+ ///
+ /// If the inner `Buf` has fewer bytes than `lim` then that is the actual
+ /// number of available bytes.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::{Buf, BufMut, buf::BufExt};
+ ///
+ /// let mut buf = b"hello world".take(2);
+ /// let mut dst = vec![];
+ ///
+ /// dst.put(&mut buf);
+ /// assert_eq!(*dst, b"he"[..]);
+ ///
+ /// dst.clear();
+ ///
+ /// buf.set_limit(3);
+ /// dst.put(&mut buf);
+ /// assert_eq!(*dst, b"llo"[..]);
+ /// ```
+ pub fn set_limit(&mut self, lim: usize) {
+ self.limit = lim
+ }
+}
+
+impl<T: Buf> Buf for Take<T> {
+ fn remaining(&self) -> usize {
+ cmp::min(self.inner.remaining(), self.limit)
+ }
+
+ fn bytes(&self) -> &[u8] {
+ let bytes = self.inner.bytes();
+ &bytes[..cmp::min(bytes.len(), self.limit)]
+ }
+
+ fn advance(&mut self, cnt: usize) {
+ assert!(cnt <= self.limit);
+ self.inner.advance(cnt);
+ self.limit -= cnt;
+ }
+}
diff --git a/third_party/rust/bytes/src/buf/ext/writer.rs b/third_party/rust/bytes/src/buf/ext/writer.rs
new file mode 100644
index 0000000000..1418418e81
--- /dev/null
+++ b/third_party/rust/bytes/src/buf/ext/writer.rs
@@ -0,0 +1,88 @@
+use crate::BufMut;
+
+use std::{cmp, io};
+
+/// A `BufMut` adapter which implements `io::Write` for the inner value.
+///
+/// This struct is generally created by calling `writer()` on `BufMut`. See
+/// documentation of [`writer()`](trait.BufMut.html#method.writer) for more
+/// details.
+#[derive(Debug)]
+pub struct Writer<B> {
+ buf: B,
+}
+
+pub fn new<B>(buf: B) -> Writer<B> {
+ Writer { buf }
+}
+
+impl<B: BufMut> Writer<B> {
+ /// Gets a reference to the underlying `BufMut`.
+ ///
+ /// It is inadvisable to directly write to the underlying `BufMut`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::buf::BufMutExt;
+ ///
+ /// let mut buf = Vec::with_capacity(1024).writer();
+ ///
+ /// assert_eq!(1024, buf.get_ref().capacity());
+ /// ```
+ pub fn get_ref(&self) -> &B {
+ &self.buf
+ }
+
+ /// Gets a mutable reference to the underlying `BufMut`.
+ ///
+ /// It is inadvisable to directly write to the underlying `BufMut`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::buf::BufMutExt;
+ ///
+ /// let mut buf = vec![].writer();
+ ///
+ /// buf.get_mut().reserve(1024);
+ ///
+ /// assert_eq!(1024, buf.get_ref().capacity());
+ /// ```
+ pub fn get_mut(&mut self) -> &mut B {
+ &mut self.buf
+ }
+
+ /// Consumes this `Writer`, returning the underlying value.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use bytes::buf::BufMutExt;
+ /// use std::io;
+ ///
+ /// let mut buf = vec![].writer();
+ /// let mut src = &b"hello world"[..];
+ ///
+ /// io::copy(&mut src, &mut buf).unwrap();
+ ///
+ /// let buf = buf.into_inner();
+ /// assert_eq!(*buf, b"hello world"[..]);
+ /// ```
+ pub fn into_inner(self) -> B {
+ self.buf
+ }
+}
+
+impl<B: BufMut + Sized> io::Write for Writer<B> {
+ fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+ let n = cmp::min(self.buf.remaining_mut(), src.len());
+
+ self.buf.put(&src[0..n]);
+ Ok(n)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+}