]> git.lizzy.rs Git - rust.git/blob - library/core/src/future/into_future.rs
Rollup merge of #103360 - ChrisDenton:isterm-filetype, r=thomcc
[rust.git] / library / core / src / future / into_future.rs
1 use crate::future::Future;
2
3 /// Conversion into a `Future`.
4 ///
5 /// By implementing `IntoFuture` for a type, you define how it will be
6 /// converted to a future.
7 ///
8 /// # `.await` desugaring
9 ///
10 /// The `.await` keyword desugars into a call to `IntoFuture::into_future`
11 /// first before polling the future to completion. `IntoFuture` is implemented
12 /// for all `T: Future` which means the `into_future` method will be available
13 /// on all futures.
14 ///
15 /// ```no_run
16 /// use std::future::IntoFuture;
17 ///
18 /// # async fn foo() {
19 /// let v = async { "meow" };
20 /// let mut fut = v.into_future();
21 /// assert_eq!("meow", fut.await);
22 /// # }
23 /// ```
24 ///
25 /// # Async builders
26 ///
27 /// When implementing futures manually there will often be a choice between
28 /// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a
29 /// good choice in most cases. But implementing `IntoFuture` is most useful when
30 /// implementing "async builder" types, which allow their values to be modified
31 /// multiple times before being `.await`ed.
32 ///
33 /// ```rust
34 /// use std::future::{ready, Ready, IntoFuture};
35 ///
36 /// /// Eventually multiply two numbers
37 /// pub struct Multiply {
38 ///     num: u16,
39 ///     factor: u16,
40 /// }
41 ///
42 /// impl Multiply {
43 ///     /// Construct a new instance of `Multiply`.
44 ///     pub fn new(num: u16, factor: u16) -> Self {
45 ///         Self { num, factor }
46 ///     }
47 ///
48 ///     /// Set the number to multiply by the factor.
49 ///     pub fn number(mut self, num: u16) -> Self {
50 ///         self.num = num;
51 ///         self
52 ///     }
53 ///
54 ///     /// Set the factor to multiply the number with.
55 ///     pub fn factor(mut self, factor: u16) -> Self {
56 ///         self.factor = factor;
57 ///         self
58 ///     }
59 /// }
60 ///
61 /// impl IntoFuture for Multiply {
62 ///     type Output = u16;
63 ///     type IntoFuture = Ready<Self::Output>;
64 ///
65 ///     fn into_future(self) -> Self::IntoFuture {
66 ///         ready(self.num * self.factor)
67 ///     }
68 /// }
69 ///
70 /// // NOTE: Rust does not yet have an `async fn main` function, that functionality
71 /// // currently only exists in the ecosystem.
72 /// async fn run() {
73 ///     let num = Multiply::new(0, 0)  // initialize the builder to number: 0, factor: 0
74 ///         .number(2)                 // change the number to 2
75 ///         .factor(2)                 // change the factor to 2
76 ///         .await;                    // convert to future and .await
77 ///
78 ///     assert_eq!(num, 4);
79 /// }
80 /// ```
81 ///
82 /// # Usage in trait bounds
83 ///
84 /// Using `IntoFuture` in trait bounds allows a function to be generic over both
85 /// `Future` and `IntoFuture`. This is convenient for users of the function, so
86 /// when they are using it they don't have to make an extra call to
87 /// `IntoFuture::into_future` to obtain an instance of `Future`:
88 ///
89 /// ```rust
90 /// use std::future::IntoFuture;
91 ///
92 /// /// Convert the output of a future to a string.
93 /// async fn fut_to_string<Fut>(fut: Fut) -> String
94 /// where
95 ///     Fut: IntoFuture,
96 ///     Fut::Output: std::fmt::Debug,
97 /// {
98 ///     format!("{:?}", fut.await)
99 /// }
100 /// ```
101 #[stable(feature = "into_future", since = "1.64.0")]
102 pub trait IntoFuture {
103     /// The output that the future will produce on completion.
104     #[stable(feature = "into_future", since = "1.64.0")]
105     type Output;
106
107     /// Which kind of future are we turning this into?
108     #[stable(feature = "into_future", since = "1.64.0")]
109     type IntoFuture: Future<Output = Self::Output>;
110
111     /// Creates a future from a value.
112     ///
113     /// # Examples
114     ///
115     /// Basic usage:
116     ///
117     /// ```no_run
118     /// use std::future::IntoFuture;
119     ///
120     /// # async fn foo() {
121     /// let v = async { "meow" };
122     /// let mut fut = v.into_future();
123     /// assert_eq!("meow", fut.await);
124     /// # }
125     /// ```
126     #[stable(feature = "into_future", since = "1.64.0")]
127     #[lang = "into_future"]
128     fn into_future(self) -> Self::IntoFuture;
129 }
130
131 #[stable(feature = "into_future", since = "1.64.0")]
132 impl<F: Future> IntoFuture for F {
133     type Output = F::Output;
134     type IntoFuture = F;
135
136     fn into_future(self) -> Self::IntoFuture {
137         self
138     }
139 }