futures_signals/
internal.rs

1use super::signal::Signal;
2use std::pin::Pin;
3use std::task::{Poll, Context};
4use pin_project::pin_project;
5
6
7#[inline]
8fn unwrap_mut<A>(x: &mut Option<A>) -> &mut A {
9    match *x {
10        Some(ref mut x) => x,
11        None => unreachable!(),
12    }
13}
14
15#[inline]
16fn unwrap_ref<A>(x: &Option<A>) -> &A {
17    match *x {
18        Some(ref x) => x,
19        None => unreachable!(),
20    }
21}
22
23
24#[derive(Debug)]
25pub struct PollResult {
26    pub done: bool,
27    pub changed: bool,
28}
29
30impl PollResult {
31    #[inline]
32    pub fn merge(self, other: Self) -> Self {
33        Self {
34            done: self.done && other.done,
35            changed: self.changed || other.changed,
36        }
37    }
38}
39
40
41#[pin_project(project = MapRef1Proj)]
42#[derive(Debug)]
43pub struct MapRef1<S> where S: Signal {
44    #[pin]
45    signal: Option<S>,
46    value: Option<S::Item>,
47}
48
49impl<S> MapRef1<S> where S: Signal {
50    #[inline]
51    pub fn new(signal: S) -> Self {
52        Self {
53            signal: Some(signal),
54            value: None,
55        }
56    }
57
58    /// DO NOT USE!
59    #[inline]
60    pub fn unsafe_pin(&mut self) -> Pin<&mut Self> {
61        // This is safe because it's only used by `map_ref`, and `map_ref` upholds the Pin contract
62        // TODO verify that this is 100% safe
63        unsafe { ::std::pin::Pin::new_unchecked(self) }
64    }
65
66    pub fn poll(self: Pin<&mut Self>, cx: &mut Context) -> PollResult {
67        let mut this = self.project();
68
69        match this.signal.as_mut().as_pin_mut().map(|signal| signal.poll_change(cx)) {
70            None => {
71                PollResult {
72                    changed: false,
73                    done: true,
74                }
75            },
76            Some(Poll::Ready(None)) => {
77                this.signal.set(None);
78
79                PollResult {
80                    changed: false,
81                    done: true,
82                }
83            },
84            Some(Poll::Ready(a)) => {
85                *this.value = a;
86
87                PollResult {
88                    changed: true,
89                    done: false,
90                }
91            },
92            Some(Poll::Pending) => {
93                PollResult {
94                    changed: false,
95                    done: false,
96                }
97            },
98        }
99    }
100
101    #[inline]
102    pub fn value_ref(&self) -> &S::Item {
103        unwrap_ref(&self.value)
104    }
105
106    #[inline]
107    pub fn value_mut(self: Pin<&mut Self>) -> &mut S::Item {
108        unwrap_mut(self.project().value)
109    }
110}
111
112
113#[pin_project(project = MapRefSignalProj)]
114#[derive(Debug)]
115#[must_use = "Signals do nothing unless polled"]
116pub struct MapRefSignal<F> {
117    callback: F,
118}
119
120impl<A, F> MapRefSignal<F> where F: FnMut(&mut Context) -> Poll<Option<A>> {
121    #[inline]
122    pub fn new(callback: F) -> Self {
123        Self { callback }
124    }
125}
126
127impl<A, F> Signal for MapRefSignal<F> where F: FnMut(&mut Context) -> Poll<Option<A>> {
128    type Item = A;
129
130    #[inline]
131    fn poll_change(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
132        let this = self.project();
133        (this.callback)(cx)
134    }
135}
136
137
138// Poll left  => Has left   => Poll right  => Has right   => Output
139// -----------------------------------------------------------------------------
140// Some(left) =>            => Some(right) =>             => Some((left, right))
141// Some(left) =>            => None        => Some(right) => Some((left, right))
142// Some(left) =>            => Pending     => Some(right) => Some((left, right))
143// None       => Some(left) => Some(right) =>             => Some((left, right))
144// Pending    => Some(left) => Some(right) =>             => Some((left, right))
145// None       => Some(left) => None        => Some(right) => None
146// None       => None       =>             =>             => None
147//            =>            => None        => None        => None
148// Some(left) =>            => Pending     => None        => Pending
149// None       => Some(left) => Pending     => Some(right) => Pending
150// None       => Some(left) => Pending     => None        => Pending
151// Pending    => Some(left) => None        => Some(right) => Pending
152// Pending    => Some(left) => Pending     => Some(right) => Pending
153// Pending    => Some(left) => Pending     => None        => Pending
154// Pending    => None       => Some(right) =>             => Pending
155// Pending    => None       => None        => Some(right) => Pending
156// Pending    => None       => Pending     => Some(right) => Pending
157// Pending    => None       => Pending     => None        => Pending