From 96268a80d44db04142ff168506e9bff8682d9a15 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Thu, 31 Oct 2019 09:39:58 -0700 Subject: [PATCH] Move "extra" methods to extension traits (#306) --- src/buf/buf_impl.rs | 107 ------------------------------ src/buf/buf_mut.rs | 59 ----------------- src/buf/{ => ext}/chain.rs | 58 ++++++---------- src/buf/ext/mod.rs | 129 ++++++++++++++++++++++++++++++++++++ src/buf/{ => ext}/reader.rs | 4 +- src/buf/{ => ext}/take.rs | 10 +-- src/buf/{ => ext}/writer.rs | 6 +- src/buf/mod.rs | 17 +---- tests/test_chain.rs | 4 +- tests/test_reader.rs | 6 +- tests/test_take.rs | 2 +- 11 files changed, 170 insertions(+), 232 deletions(-) rename src/buf/{ => ext}/chain.rs (77%) create mode 100644 src/buf/ext/mod.rs rename src/buf/{ => ext}/reader.rs (96%) rename src/buf/{ => ext}/take.rs (93%) rename src/buf/{ => ext}/writer.rs (94%) diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs index 48f8d12a4..99ecb545b 100644 --- a/src/buf/buf_impl.rs +++ b/src/buf/buf_impl.rs @@ -1,8 +1,3 @@ -use super::{Take, Chain}; - -#[cfg(feature = "std")] -use super::Reader; - use core::{cmp, ptr, mem}; #[cfg(feature = "std")] @@ -796,108 +791,6 @@ pub trait Buf { f64::from_bits(Self::get_u64_le(self)) } - /// 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 - where Self: Sized - { - super::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.to_bytes(); - /// assert_eq!(full.bytes(), b"hello world"); - /// ``` - fn chain(self, next: U) -> Chain - where Self: Sized - { - Chain::new(self, next) - } - - /// Creates a "by reference" adaptor for this instance of `Buf`. - /// - /// The returned adaptor also implements `Buf` and will simply borrow `self`. - /// - /// # Examples - /// - /// ``` - /// use bytes::{Buf, BufMut}; - /// - /// let mut buf = &b"hello world"[..]; - /// let mut dst = vec![]; - /// - /// { - /// let mut reference = buf.by_ref(); - /// dst.put(&mut reference.take(5)); - /// assert_eq!(dst, &b"hello"[..]); - /// } // drop our &mut reference so we can use `buf` again - /// - /// dst.clear(); - /// dst.put(&mut buf); - /// assert_eq!(dst, &b" world"[..]); - /// ``` - fn by_ref(&mut self) -> &mut Self where Self: Sized { - self - } - - /// 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}; - /// 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 where Self: Sized { - super::reader::new(self) - } - /// Consumes remaining bytes inside self and returns new instance of `Bytes` /// /// # Examples diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index d976ec419..8ec568aae 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,6 +1,3 @@ -#[cfg(feature = "std")] -use super::Writer; - use core::{cmp, mem::{self, MaybeUninit}, ptr, usize}; #[cfg(feature = "std")] @@ -872,62 +869,6 @@ pub trait BufMut { fn put_f64_le(&mut self, n: f64) { self.put_u64_le(n.to_bits()); } - - /// Creates a "by reference" adaptor for this instance of `BufMut`. - /// - /// The returned adapter also implements `BufMut` and will simply borrow - /// `self`. - /// - /// # Examples - /// - /// ``` - /// use bytes::BufMut; - /// use std::io; - /// - /// let mut buf = vec![]; - /// - /// { - /// let mut reference = buf.by_ref(); - /// - /// // Adapt reference to `std::io::Write`. - /// let mut writer = reference.writer(); - /// - /// // Use the buffer as a writer - /// io::Write::write(&mut writer, &b"hello world"[..]).unwrap(); - /// } // drop our &mut reference so that we can use `buf` again - /// - /// assert_eq!(buf, &b"hello world"[..]); - /// ``` - fn by_ref(&mut self) -> &mut Self where Self: Sized { - self - } - - /// 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")] - fn writer(self) -> Writer where Self: Sized { - super::writer::new(self) - } } impl BufMut for &mut T { diff --git a/src/buf/chain.rs b/src/buf/ext/chain.rs similarity index 77% rename from src/buf/chain.rs rename to src/buf/ext/chain.rs index 2805bf365..a1ec597df 100644 --- a/src/buf/chain.rs +++ b/src/buf/ext/chain.rs @@ -20,11 +20,10 @@ use crate::buf::IoSliceMut; /// # Examples /// /// ``` -/// use bytes::{Bytes, Buf}; -/// use bytes::buf::Chain; +/// use bytes::{Bytes, Buf, buf::BufExt}; /// -/// let mut buf = Bytes::from(&b"hello "[..]) -/// .chain(Bytes::from(&b"world"[..])); +/// let mut buf = (&b"hello "[..]) +/// .chain(&b"world"[..]); /// /// let full: Bytes = buf.to_bytes(); /// assert_eq!(full[..], b"hello world"[..]); @@ -41,19 +40,6 @@ pub struct Chain { impl Chain { /// Creates a new `Chain` sequencing the provided values. - /// - /// # Examples - /// - /// ``` - /// use bytes::BytesMut; - /// use bytes::buf::Chain; - /// - /// let buf = Chain::new( - /// BytesMut::with_capacity(1024), - /// BytesMut::with_capacity(1024)); - /// - /// // Use the chained buffer - /// ``` pub fn new(a: T, b: U) -> Chain { Chain { a, @@ -66,10 +52,10 @@ impl Chain { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf}; + /// use bytes::buf::BufExt; /// - /// let buf = Bytes::from(&b"hello"[..]) - /// .chain(Bytes::from(&b"world"[..])); + /// let buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); /// /// assert_eq!(buf.first_ref()[..], b"hello"[..]); /// ``` @@ -82,15 +68,15 @@ impl Chain { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf}; + /// use bytes::{Buf, buf::BufExt}; /// - /// let mut buf = Bytes::from(&b"hello "[..]) - /// .chain(Bytes::from(&b"world"[..])); + /// let mut buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); /// /// buf.first_mut().advance(1); /// - /// let full: Bytes = buf.to_bytes(); - /// assert_eq!(full[..], b"ello world"[..]); + /// let full = buf.to_bytes(); + /// assert_eq!(full, b"elloworld"[..]); /// ``` pub fn first_mut(&mut self) -> &mut T { &mut self.a @@ -101,10 +87,10 @@ impl Chain { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf}; + /// use bytes::buf::BufExt; /// - /// let buf = Bytes::from(&b"hello"[..]) - /// .chain(Bytes::from(&b"world"[..])); + /// let buf = (&b"hello"[..]) + /// .chain(&b"world"[..]); /// /// assert_eq!(buf.last_ref()[..], b"world"[..]); /// ``` @@ -117,15 +103,15 @@ impl Chain { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf}; + /// use bytes::{Buf, buf::BufExt}; /// - /// let mut buf = Bytes::from(&b"hello "[..]) - /// .chain(Bytes::from(&b"world"[..])); + /// let mut buf = (&b"hello "[..]) + /// .chain(&b"world"[..]); /// /// buf.last_mut().advance(1); /// - /// let full: Bytes = buf.to_bytes(); - /// assert_eq!(full[..], b"hello orld"[..]); + /// let full = buf.to_bytes(); + /// assert_eq!(full, b"hello orld"[..]); /// ``` pub fn last_mut(&mut self) -> &mut U { &mut self.b @@ -136,10 +122,10 @@ impl Chain { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf}; + /// use bytes::buf::BufExt; /// - /// let chain = Bytes::from(&b"hello"[..]) - /// .chain(Bytes::from(&b"world"[..])); + /// let chain = (&b"hello"[..]) + /// .chain(&b"world"[..]); /// /// let (first, last) = chain.into_inner(); /// assert_eq!(first[..], b"hello"[..]); diff --git a/src/buf/ext/mod.rs b/src/buf/ext/mod.rs new file mode 100644 index 000000000..10b9a34c0 --- /dev/null +++ b/src/buf/ext/mod.rs @@ -0,0 +1,129 @@ +//! Extra utilities for `Buf` and `BufMut` types. + +use super::{Buf, BufMut}; + +mod chain; +#[cfg(feature = "std")] +mod reader; +mod take; +#[cfg(feature = "std")] +mod writer; + +use self::take::Take; +use self::chain::Chain; + +#[cfg(feature = "std")] +use self::{reader::Reader, writer::Writer}; + +/// Extra methods for implementations of `Buf`. +pub trait BufExt: Buf { + /// Creates an adaptor which will read at most `limit` bytes from `self`. + /// + /// This function returns a new instance of `Buf` which will read at most + /// `limit` bytes. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, BufMut, buf::BufExt}; + /// + /// let mut buf = b"hello world"[..].take(5); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(dst, b"hello"); + /// + /// let mut buf = buf.into_inner(); + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(dst, b" world"); + /// ``` + fn take(self, limit: usize) -> Take + 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(self, next: U) -> Chain + 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 where Self: Sized { + reader::new(self) + } +} + +impl BufExt for B {} + +/// Extra methods for implementations of `BufMut`. +pub trait BufMutExt: BufMut { + /// Creates an adaptor which implements the `Write` trait for `self`. + /// + /// This function returns a new value which implements `Write` by adapting + /// the `Write` trait functions to the `BufMut` trait functions. Given that + /// `BufMut` operations are infallible, none of the `Write` functions will + /// return with `Err`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, buf::BufMutExt}; + /// use std::io::Write; + /// + /// let mut buf = vec![].writer(); + /// + /// let num = buf.write(&b"hello world"[..]).unwrap(); + /// assert_eq!(11, num); + /// + /// let buf = buf.into_inner(); + /// + /// assert_eq!(*buf, b"hello world"[..]); + /// ``` + #[cfg(feature = "std")] + fn writer(self) -> Writer where Self: Sized { + writer::new(self) + } +} + +impl BufMutExt for B {} diff --git a/src/buf/reader.rs b/src/buf/ext/reader.rs similarity index 96% rename from src/buf/reader.rs rename to src/buf/ext/reader.rs index 06ee1a65b..e38103b1d 100644 --- a/src/buf/reader.rs +++ b/src/buf/ext/reader.rs @@ -24,7 +24,7 @@ impl Reader { /// # Examples /// /// ```rust - /// use bytes::Buf; + /// use bytes::buf::BufExt; /// /// let mut buf = b"hello world".reader(); /// @@ -46,7 +46,7 @@ impl Reader { /// # Examples /// /// ```rust - /// use bytes::Buf; + /// use bytes::{Buf, buf::BufExt}; /// use std::io; /// /// let mut buf = b"hello world".reader(); diff --git a/src/buf/take.rs b/src/buf/ext/take.rs similarity index 93% rename from src/buf/take.rs rename to src/buf/ext/take.rs index 03f314108..6fc4ffc72 100644 --- a/src/buf/take.rs +++ b/src/buf/ext/take.rs @@ -25,7 +25,7 @@ impl Take { /// # Examples /// /// ```rust - /// use bytes::{Buf, BufMut}; + /// use bytes::buf::{Buf, BufMut, BufExt}; /// /// let mut buf = b"hello world".take(2); /// let mut dst = vec![]; @@ -50,7 +50,7 @@ impl Take { /// # Examples /// /// ```rust - /// use bytes::{Buf, BufMut}; + /// use bytes::{Buf, buf::BufExt}; /// /// let mut buf = b"hello world".take(2); /// @@ -67,7 +67,7 @@ impl Take { /// # Examples /// /// ```rust - /// use bytes::{Buf, BufMut}; + /// use bytes::{Buf, BufMut, buf::BufExt}; /// /// let mut buf = b"hello world".take(2); /// let mut dst = vec![]; @@ -91,7 +91,7 @@ impl Take { /// # Examples /// /// ```rust - /// use bytes::Buf; + /// use bytes::{Buf, buf::BufExt}; /// /// let mut buf = b"hello world".take(2); /// @@ -113,7 +113,7 @@ impl Take { /// # Examples /// /// ```rust - /// use bytes::{Buf, BufMut}; + /// use bytes::{Buf, BufMut, buf::BufExt}; /// /// let mut buf = b"hello world".take(2); /// let mut dst = vec![]; diff --git a/src/buf/writer.rs b/src/buf/ext/writer.rs similarity index 94% rename from src/buf/writer.rs rename to src/buf/ext/writer.rs index 8b357078c..1418418e8 100644 --- a/src/buf/writer.rs +++ b/src/buf/ext/writer.rs @@ -24,7 +24,7 @@ impl Writer { /// # Examples /// /// ```rust - /// use bytes::BufMut; + /// use bytes::buf::BufMutExt; /// /// let mut buf = Vec::with_capacity(1024).writer(); /// @@ -41,7 +41,7 @@ impl Writer { /// # Examples /// /// ```rust - /// use bytes::BufMut; + /// use bytes::buf::BufMutExt; /// /// let mut buf = vec![].writer(); /// @@ -58,7 +58,7 @@ impl Writer { /// # Examples /// /// ```rust - /// use bytes::BufMut; + /// use bytes::buf::BufMutExt; /// use std::io; /// /// let mut buf = vec![].writer(); diff --git a/src/buf/mod.rs b/src/buf/mod.rs index 1448abdea..d4538f21e 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -18,25 +18,14 @@ mod buf_impl; mod buf_mut; -mod chain; +pub mod ext; mod iter; -mod take; mod vec_deque; -// When std::io::Reader etc. traits are not available, skip these -#[cfg(feature = "std")] -mod reader; -#[cfg(feature = "std")] -mod writer; - pub use self::buf_impl::Buf; pub use self::buf_mut::BufMut; +pub use self::ext::{BufExt, BufMutExt}; #[cfg(feature = "std")] pub use self::buf_mut::IoSliceMut; -pub use self::chain::Chain; pub use self::iter::IntoIter; -#[cfg(feature = "std")] -pub use self::reader::Reader; -pub use self::take::Take; -#[cfg(feature = "std")] -pub use self::writer::Writer; + diff --git a/tests/test_chain.rs b/tests/test_chain.rs index 2887575a5..877618843 100644 --- a/tests/test_chain.rs +++ b/tests/test_chain.rs @@ -1,7 +1,7 @@ #![deny(warnings, rust_2018_idioms)] use bytes::{Buf, BufMut, Bytes, BytesMut}; -use bytes::buf::Chain; +use bytes::buf::BufExt; use std::io::IoSlice; #[test] @@ -19,7 +19,7 @@ fn writing_chained() { let mut b = BytesMut::with_capacity(64); { - let mut buf = Chain::new(&mut a, &mut b); + let mut buf = (&mut a).chain(&mut b); for i in 0u8..128 { buf.put_u8(i); diff --git a/tests/test_reader.rs b/tests/test_reader.rs index 89a78497a..9c5972a96 100644 --- a/tests/test_reader.rs +++ b/tests/test_reader.rs @@ -2,13 +2,13 @@ use std::io::{BufRead, Read}; -use bytes::Buf; +use bytes::buf::{BufExt}; #[test] fn read() { let buf1 = &b"hello "[..]; let buf2 = &b"world"[..]; - let buf = Buf::chain(buf1, buf2); // Disambiguate with Read::chain + let buf = BufExt::chain(buf1, buf2); // Disambiguate with Read::chain let mut buffer = Vec::new(); buf.reader().read_to_end(&mut buffer).unwrap(); assert_eq!(b"hello world", &buffer[..]); @@ -18,7 +18,7 @@ fn read() { fn buf_read() { let buf1 = &b"hell"[..]; let buf2 = &b"o\nworld"[..]; - let mut reader = Buf::chain(buf1, buf2).reader(); + let mut reader = BufExt::chain(buf1, buf2).reader(); let mut line = String::new(); reader.read_line(&mut line).unwrap(); assert_eq!("hello\n", &line); diff --git a/tests/test_take.rs b/tests/test_take.rs index 7d043183f..b9b525b1f 100644 --- a/tests/test_take.rs +++ b/tests/test_take.rs @@ -1,6 +1,6 @@ #![deny(warnings, rust_2018_idioms)] -use bytes::Buf; +use bytes::buf::{Buf, BufExt}; #[test] fn long_take() {