futures_stable/lib.rs
1#![no_std]
2#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
3#![cfg_attr(feature = "nightly", feature(pin))]
4
5macro_rules! if_nightly {
6 ($($i:item)*) => ($(
7 #[cfg(feature = "nightly")]
8 $i
9 )*)
10}
11
12if_nightly! {
13 macro_rules! if_std {
14 ($($i:item)*) => ($(
15 #[cfg(feature = "std")]
16 $i
17 )*)
18 }
19
20 extern crate futures_core;
21 extern crate futures_executor;
22
23 use core::mem::PinMut;
24 use futures_core::{Future, Stream, Poll, task};
25
26 if_std! {
27 extern crate std;
28
29 mod executor;
30 mod unsafe_pin;
31
32 use std::boxed::PinBox;
33
34 pub use executor::{StableExecutor, block_on_stable};
35 use unsafe_pin::UnsafePin;
36 }
37
38 /// A trait for `Future`s which can be pinned to a particular location in memory.
39 ///
40 /// These futures take `self` by `PinMut<Self>`, rather than `&mut Self`.
41 /// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
42 /// that they won't be moved after being polled. Since they won't be moved, it's
43 /// possible for them to safely contain references to themselves.
44 ///
45 /// The most common examples of such self-referential `StableFuture`s are `#[async]`
46 /// functions and `async_block!`s.
47 ///
48 /// All types which implement `Future` also implement `StableFuture` automatically.
49 pub trait StableFuture {
50 /// A successful value
51 type Item;
52
53 /// An error
54 type Error;
55
56 /// Attempt to resolve the future to a final value, registering the current task
57 /// for wakeup if the value is not yet available.
58 ///
59 /// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
60 /// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
61 /// guaranteeing that the location of `self` will not change after a call to `poll`.
62 fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error>;
63
64 /// Pin the future to a particular location by placing it on the heap.
65 #[cfg(feature = "std")]
66 fn pin<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + Send + 'a>
67 where Self: Send + Sized + 'a
68 {
69 PinBox::new(unsafe { UnsafePin::new(self) })
70 }
71
72 /// Pin the future to a particular location by placing it on the heap.
73 ///
74 /// This method is the same as `pin`, but doesn't require that `Self` can be
75 /// safely sent across threads. `pin` should be preferred where possible.
76 #[cfg(feature = "std")]
77 fn pin_local<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + 'a>
78 where Self: Sized + 'a
79 {
80 PinBox::new(unsafe { UnsafePin::new(self) })
81 }
82 }
83
84 impl<F: Future> StableFuture for F {
85 type Item = F::Item;
86 type Error = F::Error;
87
88 fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
89 F::poll(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
90 }
91 }
92
93 /// A trait for `Stream`s which can be pinned to a particular location in memory.
94 ///
95 /// These streams take `self` by `PinMut<Self>`, rather than `&mut Self`.
96 /// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
97 /// that they won't be moved after being polled. Since they won't be moved, it's
98 /// possible for them to safely contain references to themselves.
99 ///
100 /// The most common examples of such self-referential `StableStream`s are
101 /// `#[async_stream(item = Foo)]` functions.
102 ///
103 /// All types which implement `Stream` also implement `StableStream` automatically.
104 pub trait StableStream {
105 /// A successful value
106 type Item;
107 /// An error
108 type Error;
109
110 /// Attempt to resolve the stream to the next value, registering the current task
111 /// for wakeup if the value is not yet available.
112 ///
113 /// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
114 /// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
115 /// guaranteeing that the location of `self` will not change after a call to `poll`.
116 fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error>;
117
118 /// Pin the stream to a particular location by placing it on the heap.
119 #[cfg(feature = "std")]
120 fn pin<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + Send + 'a>
121 where Self: Send + Sized + 'a
122 {
123 PinBox::new(unsafe { UnsafePin::new(self) })
124 }
125
126 /// Pin the stream to a particular location by placing it on the heap.
127 ///
128 /// This method is the same as `pin`, but doesn't require that `Self` can be
129 /// safely sent across threads. `pin` should be preferred where possible.
130 #[cfg(feature = "std")]
131 fn pin_local<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + 'a>
132 where Self: Sized + 'a
133 {
134 PinBox::new(unsafe { UnsafePin::new(self) })
135 }
136 }
137
138 impl<S: Stream> StableStream for S {
139 type Item = S::Item;
140 type Error = S::Error;
141
142 fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
143 S::poll_next(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
144 }
145 }
146}