Trait std::future::IntoFuture
source · [−]pub trait IntoFuture {
type Output;
type IntoFuture: Future
where
<Self::IntoFuture as Future>::Output == Self::Output;
fn into_future(self) -> Self::IntoFuture;
}
Expand description
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.
#![feature(into_future)]
use std::future::IntoFuture;
let v = async { "meow" };
let mut fut = v.into_future();
assert_eq!("meow", fut.await);
RunAsync 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.
#![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<Self::Output>;
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);
}
RunUsage 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
:
#![feature(into_future)]
use std::future::IntoFuture;
/// Convert the output of a future to a string.
async fn fut_to_string<Fut>(fut: Fut) -> String
where
Fut: IntoFuture,
Fut::Output: std::fmt::Debug,
{
format!("{:?}", fut.await)
}
RunRequired Associated Types
The output that the future will produce on completion.
type IntoFuture: Future
where
<Self::IntoFuture as Future>::Output == Self::Output
type IntoFuture: Future
where
<Self::IntoFuture as Future>::Output == Self::Output
Which kind of future are we turning this into?