1use core::future::Future;
2use core::pin::Pin;
3use core::task::{Context, Poll};
4
5use crate::error::{AlreadyDroppedScheduler, FutureResult};
6use crate::selector::Selector;
7use crate::task::StateRef;
8
9pub(in crate) struct TaskFuture<'state, State, Selector, const SAFETY: bool> {
10 pub(in crate) selector: Selector,
11 pub(in crate) state: StateRef<'state, State>,
12}
13
14
15impl<'state, State, Sel> Future for TaskFuture<'state, State, Sel, true>
16 where
17 Sel: Selector<State>,
18 State: Clone + 'state
19{
20 type Output = FutureResult<Sel::Output>;
21
22 #[inline]
23 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
24 match self.try_poll(cx) {
25 Err(e) => Poll::Ready(Err(e)),
26 Ok(Some(output)) => Poll::Ready(Ok(output)),
27 Ok(None) => Poll::Pending
28 }
29 }
30}
31
32impl<'state, State, Sel> Future for TaskFuture<'state, State, Sel, false>
33 where
34 Sel: Selector<State>,
35 State: Clone + 'state
36{
37 type Output = Sel::Output;
38
39 #[allow(clippy::panic)]
40 #[inline(always)]
41 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
42 match self.try_poll(cx) {
43 Err(e) => {
44 panic!("{e}");
45 }
46 Ok(Some(output)) => Poll::Ready(output),
47 Ok(None) => Poll::Pending
48 }
49 }
50}
51
52impl<'state, State, Sel, const SAFETY: bool> TaskFuture<'state, State, Sel, SAFETY>
53 where
54 Sel: Selector<State>,
55 State: Clone + 'state
56{
57 fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<Option<Sel::Output>, AlreadyDroppedScheduler> {
58 let state = self.state.as_ref().ok_or(AlreadyDroppedScheduler)?.clone();
59 if let Some(output) = self.selector.select(state) {
60 Ok(Some(output))
61 } else {
62 cx.waker().wake_by_ref();
63 Ok(None)
64 }
65 }
66}
67
68impl<'state, State, Sel> TaskFuture<'state, State, Sel, false>
69 where
70 Sel: Selector<State>
71{
72 #[allow(unused)]
73 fn new_non_safety(state: StateRef<'state, State>, selector: Sel) -> TaskFuture<'state, State, Sel, false> {
74 Self {
75 selector,
76 state,
77 }
78 }
79}