maycoon_core/tasks/
task.rs

1use std::pin::Pin;
2use std::task::{Context, Poll};
3
4/// A task that **can** be spawned on a background thread.
5///
6/// The inner value requires to be [Send] and `static`.
7pub trait Task<T: Send + 'static>: Future<Output = T> + Send + 'static {
8    /// Returns if the task is finished or still pending.
9    fn is_ready(&self) -> bool;
10
11    /// Tries to take the inner value if the task is finished.
12    ///
13    /// Returns [None] if the task is still pending.
14    ///
15    /// This should only be called if you are sure the task is ready (check via [Task::is_ready]).
16    /// Furthermore, calling this multiple times when the task is finished will probably raise a panic,
17    /// so make sure to only call this once, if the task is finished.
18    fn take(&mut self) -> Option<T>;
19}
20
21/// A task that is executed on the local thread.
22///
23/// Unlike [Task], the inner type does not need to be [Send].
24pub trait LocalTask<T>: Future<Output = T> + 'static {
25    /// Returns if the task is finished or still pending.
26    fn is_ready(&self) -> bool;
27
28    /// Tries to take the inner value if the task is finished.
29    ///
30    /// Returns [None] if the task is still pending.
31    ///
32    /// This should only be called if you are sure the task is ready (check via [Task::is_ready]).
33    /// Furthermore, calling this multiple times when the task is finished will probably raise a panic,
34    /// so make sure to only call this once, if the task is finished.
35    fn take(&mut self) -> Option<T>;
36}
37
38/// A task that never completes.
39///
40/// This is the [Send]-safe variant of [LocalNeverTask].
41#[derive(Debug)]
42pub struct NeverTask<T: Send + 'static>(std::marker::PhantomData<T>);
43
44impl<T: Send + 'static> NeverTask<T> {
45    /// Creates a new [NeverTask].
46    #[inline(always)]
47    pub const fn new() -> Self {
48        Self(std::marker::PhantomData)
49    }
50}
51
52impl<T: Send + 'static> Future for NeverTask<T> {
53    type Output = T;
54
55    #[inline(always)]
56    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
57        Poll::Pending
58    }
59}
60
61impl<T: Send + 'static> Task<T> for NeverTask<T> {
62    #[inline(always)]
63    fn is_ready(&self) -> bool {
64        false
65    }
66
67    #[inline(always)]
68    fn take(&mut self) -> Option<T> {
69        None
70    }
71}
72
73impl<T: Send + 'static> Default for NeverTask<T> {
74    #[inline(always)]
75    fn default() -> Self {
76        Self::new()
77    }
78}
79
80/// A task that never completes.
81///
82/// This is the non-[Send]-safe variant of [NeverTask].
83#[derive(Debug, Default)]
84pub struct LocalNeverTask<T: 'static>(std::marker::PhantomData<T>);
85
86impl<T: 'static> LocalNeverTask<T> {
87    /// Create a new [LocalNeverTask].
88    #[inline(always)]
89    pub const fn new() -> Self {
90        Self(std::marker::PhantomData)
91    }
92}
93
94impl<T: 'static> Future for LocalNeverTask<T> {
95    type Output = T;
96
97    #[inline(always)]
98    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
99        Poll::Pending
100    }
101}
102
103impl<T: 'static> LocalTask<T> for LocalNeverTask<T> {
104    #[inline(always)]
105    fn is_ready(&self) -> bool {
106        false
107    }
108
109    #[inline(always)]
110    fn take(&mut self) -> Option<T> {
111        None
112    }
113}