futures_stable/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#![no_std]
#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
#![cfg_attr(feature = "nightly", feature(pin))]

macro_rules! if_nightly {
    ($($i:item)*) => ($(
        #[cfg(feature = "nightly")]
        $i
    )*)
}

if_nightly! {
    macro_rules! if_std {
        ($($i:item)*) => ($(
            #[cfg(feature = "std")]
            $i
        )*)
    }

    extern crate futures_core;
    extern crate futures_executor;

    use core::mem::PinMut;
    use futures_core::{Future, Stream, Poll, task};

    if_std! {
        extern crate std;

        mod executor;
        mod unsafe_pin;

        use std::boxed::PinBox;

        pub use executor::{StableExecutor, block_on_stable};
        use unsafe_pin::UnsafePin;
    }

    /// A trait for `Future`s which can be pinned to a particular location in memory.
    ///
    /// These futures take `self` by `PinMut<Self>`, rather than `&mut Self`.
    /// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
    /// that they won't be moved after being polled. Since they won't be moved, it's
    /// possible for them to safely contain references to themselves.
    ///
    /// The most common examples of such self-referential `StableFuture`s are `#[async]`
    /// functions and `async_block!`s.
    ///
    /// All types which implement `Future` also implement `StableFuture` automatically.
    pub trait StableFuture {
        /// A successful value
        type Item;

        /// An error
        type Error;

        /// Attempt to resolve the future to a final value, registering the current task
        /// for wakeup if the value is not yet available.
        ///
        /// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
        /// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
        /// guaranteeing that the location of `self` will not change after a call to `poll`.
        fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error>;

        /// Pin the future to a particular location by placing it on the heap.
        #[cfg(feature = "std")]
        fn pin<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + Send + 'a>
            where Self: Send + Sized + 'a
        {
            PinBox::new(unsafe { UnsafePin::new(self) })
        }

        /// Pin the future to a particular location by placing it on the heap.
        ///
        /// This method is the same as `pin`, but doesn't require that `Self` can be
        /// safely sent across threads. `pin` should be preferred where possible.
        #[cfg(feature = "std")]
        fn pin_local<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + 'a>
            where Self: Sized + 'a
        {
            PinBox::new(unsafe { UnsafePin::new(self) })
        }
    }

    impl<F: Future> StableFuture for F {
        type Item = F::Item;
        type Error = F::Error;

        fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
            F::poll(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
        }
    }

    /// A trait for `Stream`s which can be pinned to a particular location in memory.
    ///
    /// These streams take `self` by `PinMut<Self>`, rather than `&mut Self`.
    /// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
    /// that they won't be moved after being polled. Since they won't be moved, it's
    /// possible for them to safely contain references to themselves.
    ///
    /// The most common examples of such self-referential `StableStream`s are
    /// `#[async_stream(item = Foo)]` functions.
    ///
    /// All types which implement `Stream` also implement `StableStream` automatically.
    pub trait StableStream {
        /// A successful value
        type Item;
        /// An error
        type Error;

        /// Attempt to resolve the stream to the next value, registering the current task
        /// for wakeup if the value is not yet available.
        ///
        /// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
        /// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
        /// guaranteeing that the location of `self` will not change after a call to `poll`.
        fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error>;

        /// Pin the stream to a particular location by placing it on the heap.
        #[cfg(feature = "std")]
        fn pin<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + Send + 'a>
            where Self: Send + Sized + 'a
        {
            PinBox::new(unsafe { UnsafePin::new(self) })
        }

        /// Pin the stream to a particular location by placing it on the heap.
        ///
        /// This method is the same as `pin`, but doesn't require that `Self` can be
        /// safely sent across threads. `pin` should be preferred where possible.
        #[cfg(feature = "std")]
        fn pin_local<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + 'a>
            where Self: Sized + 'a
        {
            PinBox::new(unsafe { UnsafePin::new(self) })
        }
    }

    impl<S: Stream> StableStream for S {
        type Item = S::Item;
        type Error = S::Error;

        fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
            S::poll_next(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
        }
    }
}