maycoon_core/tasks/runner/
mod.rs

1use crate::tasks::task::{LocalTask, Task};
2use std::fmt::Debug;
3
4/// Contains implementations of [Task], [LocalTask] and [TaskRunnerImpl] using [tokio].
5#[cfg(all(native, feature = "tokio-runner"))]
6pub mod tokio;
7
8/// A task runner that can be used to spawn tasks.
9///
10/// The fields will only be available, if the corresponding feature is enabled.
11#[derive(Debug)]
12pub enum TaskRunner {
13    /// A task runner that uses the [tokio] runtime.
14    #[cfg(feature = "tokio-runner")]
15    Tokio(tokio::TaskRunner),
16    /// A dummy task runner that will panic on any method call.
17    /// Useful if you want to disable the task runner feature,
18    /// but still want the build script to work (e.g. for libraries).
19    #[cfg(feature = "dummy-runner")]
20    Dummy,
21}
22
23impl TaskRunner {
24    /// Spawns a task, possibly in the background.
25    ///
26    /// Returns a task handle to the future.
27    ///
28    /// Panics, when no task runner feature is enabled.
29    #[inline(always)]
30    #[tracing::instrument(skip_all)]
31    pub fn spawn<Fut>(&self, _future: Fut) -> Box<dyn Task<Fut::Output>>
32    where
33        Fut: Future + Send + 'static,
34        Fut::Output: Send + 'static,
35    {
36        match self {
37            #[cfg(feature = "tokio-runner")]
38            TaskRunner::Tokio(rt) => Box::new(rt.spawn(_future)),
39
40            _ => {
41                panic!(
42                    "No valid task runner feature selected. Please select a `-runner` feature (e.g. `tokio-runner`)."
43                );
44
45                // Required for code to compile
46                #[allow(unreachable_code)]
47                Box::new(crate::tasks::task::NeverTask::new())
48            },
49        }
50    }
51
52    /// Spawns a blocking task in the background.
53    ///
54    /// Returns a task handle to the operation.
55    ///
56    /// Panics, when no task runner feature is enabled.
57    #[inline(always)]
58    #[cfg(native)]
59    #[tracing::instrument(skip_all)]
60    pub fn spawn_blocking<R, F>(&self, _func: F) -> Box<dyn Task<R>>
61    where
62        R: Send + 'static,
63        F: FnOnce() -> R + Send + 'static,
64    {
65        match self {
66            #[cfg(feature = "tokio-runner")]
67            TaskRunner::Tokio(rt) => Box::new(rt.spawn_blocking(_func)),
68
69            _ => {
70                panic!(
71                    "No valid task runner feature selected. Please select a `-runner` feature (e.g. `tokio-runner`)."
72                );
73
74                // Required for code to compile
75                #[allow(unreachable_code)]
76                Box::new(crate::tasks::task::NeverTask::new())
77            },
78        }
79    }
80
81    /// Blocks on the given future, until it's completed.
82    ///
83    /// Panics, when no task runner feature is enabled.
84    #[inline(always)]
85    #[cfg(native)]
86    #[tracing::instrument(skip_all)]
87    pub fn block_on<Fut>(&self, _future: Fut) -> Fut::Output
88    where
89        Fut: Future,
90    {
91        match self {
92            #[cfg(feature = "tokio-runner")]
93            TaskRunner::Tokio(rt) => rt.block_on(_future),
94
95            _ => panic!(
96                "No valid task runner feature selected. Please select a `-runner` feature (e.g. `tokio-runner`)."
97            ),
98        }
99    }
100}
101
102/// A trait that provides a task runner implementation.
103pub trait TaskRunnerImpl: Debug + 'static {
104    /// The task type, that this task runner implementation uses.
105    type Task<T: Send + 'static>: Task<T>;
106
107    /// The local task type, that this task runner implementation uses.
108    type LocalTask<T: 'static>: LocalTask<T>;
109
110    /// Spawns a task, possibly in the background.
111    ///
112    /// Returns a task handle to the future.
113    fn spawn<Fut>(&self, future: Fut) -> Self::Task<Fut::Output>
114    where
115        Fut: Future + Send + 'static,
116        Fut::Output: Send + 'static;
117
118    /// Spawns a blocking task in the background.
119    ///
120    /// Returns a task handle to the operation.
121    #[cfg(native)]
122    fn spawn_blocking<R, F>(&self, func: F) -> Self::Task<R>
123    where
124        R: Send + 'static,
125        F: FnOnce() -> R + Send + 'static;
126
127    /// Blocks on the given future, until it's completed.
128    #[cfg(native)]
129    fn block_on<Fut>(&self, future: Fut) -> Fut::Output
130    where
131        Fut: Future;
132}