1use futures::Future;
5
6pub unsafe trait Spawner<T> {
7 type FutureOutput;
8 type SpawnHandle: Future<Output = Self::FutureOutput> + Send;
9 fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle;
10}
11
12pub unsafe trait FuncSpawner<T> {
13 type FutureOutput;
14 type SpawnHandle: Future<Output = Self::FutureOutput> + Send;
15 fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle;
16}
17
18pub unsafe trait Blocker {
19 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T;
20}
21
22#[cfg(feature = "use-async-std")]
23pub mod use_async_std {
24 use super::*;
25 use async_std::task::{block_on, spawn, spawn_blocking, JoinHandle};
26
27 #[derive(Default)]
28 pub struct AsyncStd;
29
30 unsafe impl<T: Send + 'static> Spawner<T> for AsyncStd {
31 type FutureOutput = T;
32 type SpawnHandle = JoinHandle<T>;
33
34 fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
35 spawn(f)
36 }
37 }
38 unsafe impl<T: Send + 'static> FuncSpawner<T> for AsyncStd {
39 type FutureOutput = T;
40 type SpawnHandle = JoinHandle<T>;
41
42 fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
43 spawn_blocking(f)
44 }
45 }
46 unsafe impl Blocker for AsyncStd {
47 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
48 block_on(f)
49 }
50 }
51}
52
53#[cfg(feature = "use-tokio")]
54pub mod use_tokio {
55 use super::*;
56 use tokio::task as tokio_task;
57
58 #[derive(Default)]
59 pub struct Tokio;
60
61 unsafe impl<T: Send + 'static> Spawner<T> for Tokio {
62 type FutureOutput = Result<T, tokio_task::JoinError>;
63 type SpawnHandle = tokio_task::JoinHandle<T>;
64
65 fn spawn<F: Future<Output = T> + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
66 tokio_task::spawn(f)
67 }
68 }
69
70 unsafe impl<T: Send + 'static> FuncSpawner<T> for Tokio {
71 type FutureOutput = Result<T, tokio_task::JoinError>;
72 type SpawnHandle = tokio_task::JoinHandle<T>;
73
74 fn spawn_func<F: FnOnce() -> T + Send + 'static>(&self, f: F) -> Self::SpawnHandle {
75 tokio_task::spawn_blocking(f)
76 }
77 }
78
79 unsafe impl Blocker for Tokio {
80 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
81 tokio_task::block_in_place(|| {
82 tokio::runtime::Builder::new_current_thread()
83 .build()
84 .unwrap()
85 .block_on(f)
86 })
87 }
88 }
89}