futures_signals/
internal.rs1use 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 #[inline]
60 pub fn unsafe_pin(&mut self) -> Pin<&mut Self> {
61 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