Skip to main content

yaaral/
lib.rs

1#![doc = include_str!("../README.MD")]
2#![warn(missing_docs)]
3
4use std::fmt::Debug;
5
6use std::future::Future;
7
8mod extensions;
9pub mod prelude;
10mod utils;
11
12#[cfg(any(feature = "bevy_runtime", feature = "bevy_runtime_018"))]
13pub mod bevy;
14
15#[cfg(feature = "futures_runtime")]
16pub mod futures;
17
18#[cfg(feature = "tokio_runtime")]
19pub mod tokio;
20
21pub use utils::Infallible;
22
23#[cfg(feature = "compat")]
24pub use extensions::compat;
25
26#[cfg(feature = "http")]
27pub use extensions::http;
28
29#[cfg(feature = "time")]
30pub use extensions::time;
31
32/// Interface for a task
33pub trait TaskHandle {
34    /// The type returned by the future
35    type Output;
36    /// The error that can be returned when joining
37    type JoinError: Debug;
38    /// Join the task, wait for completion, and return its output
39    fn join(self) -> impl Future<Output = Result<Self::Output, Self::JoinError>>;
40    /// Abort the task
41    fn abort(self);
42    /// Cancel the task, and wait for the cancellation to finish
43    fn cancel(self) -> impl Future<Output = ()> + Send;
44    /// Detach, so that the task keep executing in the background
45    fn detach(self);
46}
47
48/// Allow to detach a `Result<TaskHandle>`
49pub trait TaskReturnHandle {
50    /// The error type
51    type Error;
52    /// Detach, so that the task keep executing in the background
53    fn detach(self) -> Result<(), Self::Error>;
54}
55
56impl<TH, E> TaskReturnHandle for Result<TH, E>
57where
58    TH: TaskHandle,
59{
60    type Error = E;
61    fn detach(self) -> Result<(), Self::Error> {
62        self.map(|x| x.detach())
63    }
64}
65
66/// Interface for managing task for runtimes
67pub trait TaskInterface: Send + Sync + Clone + 'static {
68    /// Result of spawning a task
69    type TaskHandle<T: 'static + Send>: TaskHandle<Output = T, JoinError = Self::JoinError>;
70
71    /// Error type for errors occuring during spawning
72    type SpawnError: Debug;
73
74    /// Error type when creating
75    type JoinError: Debug;
76
77    /// Spawn a task
78    fn spawn_task<F, T>(
79        &self,
80        future: F,
81    ) -> Result<utils::TaskHandle<Self::TaskHandle<F::Output>>, Self::SpawnError>
82    where
83        F: Future<Output = T> + Send + 'static,
84        T: Send + 'static;
85
86    /// Block on task
87    fn block_on<F: Future>(&self, future: F) -> F::Output;
88}
89
90/// Configuration of a runtime
91pub struct Config {
92    pub(crate) thread_count: Option<usize>,
93    pub(crate) prefix: Option<String>,
94}
95
96impl Config {
97    /// New default config, with default number of threads.
98    pub fn new() -> Self {
99        Self {
100            thread_count: None,
101            prefix: None,
102        }
103    }
104    /// Prefix of the runtime threads
105    pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
106        self.prefix = Some(prefix.into());
107        self
108    }
109    /// Set the number of threads
110    pub fn thread_count(mut self, thread_count: usize) -> Self {
111        self.thread_count = Some(thread_count);
112        self
113    }
114}
115
116impl Default for Config {
117    fn default() -> Self {
118        Self::new()
119    }
120}
121
122/// Full interface for Runtime, including creation
123pub trait CreationInterface: TaskInterface {
124    /// Error type when creating
125    type NewError: Debug;
126
127    /// Create a new runtime
128    fn new(config: Config) -> Result<Self, Self::NewError>;
129}
130
131#[cfg(test)]
132#[path = "../tests/common/mod.rs"]
133mod common;
134
135#[cfg(all(test, any(feature = "futures_runtime", feature = "tokio_runtime")))]
136mod test {
137    use super::common;
138
139    use crate::{Config, CreationInterface};
140
141    fn test_full_runtime<RT: CreationInterface>() {
142        let rt = RT::new(Config::new().prefix("test")).unwrap();
143        common::test_runtime_tasks(&rt);
144    }
145    #[cfg(feature = "futures_runtime")]
146    #[test]
147    fn test_futures() {
148        test_full_runtime::<crate::futures::Runtime>();
149    }
150    #[cfg(feature = "tokio_runtime")]
151    #[test]
152    fn test_tokio() {
153        test_full_runtime::<crate::tokio::Runtime>();
154    }
155}