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