diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs index 8014dacdd98da..d22094130ad9a 100644 --- a/library/core/src/future/into_future.rs +++ b/library/core/src/future/into_future.rs @@ -1,6 +1,109 @@ use crate::future::Future; /// Conversion into a `Future`. +/// +/// By implementing `Intofuture` for a type, you define how it will be +/// converted to a future. +/// +/// # `.await` desugaring +/// +/// The `.await` keyword desugars into a call to `IntoFuture::into_future` +/// first before polling the future to completion. `IntoFuture` is implemented +/// for all `T: Future` which means the `into_future` method will be available +/// on all futures. +/// +/// ```no_run +/// #![feature(into_future)] +/// +/// use std::future::IntoFuture; +/// +/// # async fn foo() { +/// let v = async { "meow" }; +/// let mut fut = v.into_future(); +/// assert_eq!("meow", fut.await); +/// # } +/// ``` +/// +/// # Async builders +/// +/// When implementing futures manually there will often be a choice between +/// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a +/// good choice in most cases. But implementing `IntoFuture` is most useful when +/// implementing "async builder" types, which allows the type to be modified +/// multiple times before being `.await`ed. +/// +/// ```rust +/// #![feature(into_future)] +/// +/// use std::future::{ready, Ready, IntoFuture}; +/// +/// /// Eventually multiply two numbers +/// pub struct Multiply { +/// num: u16, +/// factor: u16, +/// } +/// +/// impl Multiply { +/// /// Construct a new instance of `Multiply`. +/// pub fn new(num: u16, factor: u16) -> Self { +/// Self { num, factor } +/// } +/// +/// /// Set the number to multiply by the factor. +/// pub fn number(mut self, num: u16) -> Self { +/// self.num = num; +/// self +/// } +/// +/// /// Set the factor to multiply the number with. +/// pub fn factor(mut self, factor: u16) -> Self { +/// self.factor = factor; +/// self +/// } +/// } +/// +/// impl IntoFuture for Multiply { +/// type Output = u16; +/// type IntoFuture = Ready; +/// +/// fn into_future(self) -> Self::IntoFuture { +/// ready(self.num * self.factor) +/// } +/// } +/// +/// // NOTE: Rust does not yet have an `async fn main` function, that functionality +/// // currently only exists in the ecosystem. +/// async fn run() { +/// let num = Multiply::new(0, 0) // initialize the builder to number: 0, factor: 0 +/// .number(2) // change the number to 2 +/// .factor(2) // change the factor to 2 +/// .await; // convert to future and .await +/// +/// assert_eq!(num, 4); +/// } +/// ``` +/// +/// # Usage in trait bounds +/// +/// Using `IntoFuture` in trait bounds allows a function to be generic over both +/// `Future` and `IntoFuture`. This is convenient for users of the function, so +/// when they are using it they don't have to make an extra call to +/// `IntoFuture::into_future` to obtain an instance of `Future`: +/// +/// ```rust +/// #![feature(into_future)] +/// +/// use std::future::IntoFuture; +/// +/// /// Convert the output of a future to a string. +/// async fn fut_to_string(fut: Fut) -> String +/// where +/// Fut: IntoFuture, +/// Fut::Output: std::fmt::Debug, +/// { +/// format!("{:?}", fut.await) +/// } +/// ``` #[unstable(feature = "into_future", issue = "67644")] pub trait IntoFuture { /// The output that the future will produce on completion. @@ -12,6 +115,22 @@ pub trait IntoFuture { type IntoFuture: Future; /// Creates a future from a value. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```no_run + /// #![feature(into_future)] + /// + /// use std::future::IntoFuture; + /// + /// # async fn foo() { + /// let v = async { "meow" }; + /// let mut fut = v.into_future(); + /// assert_eq!("meow", fut.await); + /// # } + /// ``` #[unstable(feature = "into_future", issue = "67644")] #[lang = "into_future"] fn into_future(self) -> Self::IntoFuture; diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index 0ca58efe1fe2f..95072547302eb 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -441,14 +441,12 @@ impl Read for VecDeque { impl Write for VecDeque { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { - self.reserve(buf.len()); self.extend(buf); Ok(buf.len()) } #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.reserve(buf.len()); self.extend(buf); Ok(()) } diff --git a/library/std/src/io/readbuf.rs b/library/std/src/io/readbuf.rs index c655bc889308c..78d1113f8375a 100644 --- a/library/std/src/io/readbuf.rs +++ b/library/std/src/io/readbuf.rs @@ -166,8 +166,8 @@ impl<'a> ReadBuf<'a> { /// /// The number of initialized bytes is not changed, and the contents of the buffer are not modified. #[inline] - pub fn clear(&mut self) { - self.set_filled(0); // The assertion in `set_filled` is optimized out + pub fn clear(&mut self) -> &mut Self { + self.set_filled(0) // The assertion in `set_filled` is optimized out } /// Increases the size of the filled region of the buffer. @@ -178,8 +178,8 @@ impl<'a> ReadBuf<'a> { /// /// Panics if the filled region of the buffer would become larger than the initialized region. #[inline] - pub fn add_filled(&mut self, n: usize) { - self.set_filled(self.filled + n); + pub fn add_filled(&mut self, n: usize) -> &mut Self { + self.set_filled(self.filled + n) } /// Sets the size of the filled region of the buffer. @@ -193,10 +193,11 @@ impl<'a> ReadBuf<'a> { /// /// Panics if the filled region of the buffer would become larger than the initialized region. #[inline] - pub fn set_filled(&mut self, n: usize) { + pub fn set_filled(&mut self, n: usize) -> &mut Self { assert!(n <= self.initialized); self.filled = n; + self } /// Asserts that the first `n` unfilled bytes of the buffer are initialized. @@ -208,8 +209,9 @@ impl<'a> ReadBuf<'a> { /// /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized. #[inline] - pub unsafe fn assume_init(&mut self, n: usize) { + pub unsafe fn assume_init(&mut self, n: usize) -> &mut Self { self.initialized = cmp::max(self.initialized, self.filled + n); + self } /// Appends data to the buffer, advancing the written position and possibly also the initialized position. @@ -227,7 +229,9 @@ impl<'a> ReadBuf<'a> { } // SAFETY: We just added the entire contents of buf to the filled section. - unsafe { self.assume_init(buf.len()) } + unsafe { + self.assume_init(buf.len()); + } self.add_filled(buf.len()); }