1mod executor;
2
3pub use crate::global::executor::{BuiltinExecutor, DefaultExecutor};
4use crate::{Executor, ExecutorBlockOn, ExecutorBlocking, ExecutorTimeout, JoinHandle};
5use std::fmt::Debug;
6
7pub struct ConfiguredExecutor<E = DefaultExecutor> {
8 executor: E,
9 task_executor: Option<BuiltinExecutor>,
10}
11
12impl<E: Default> Default for ConfiguredExecutor<E> {
13 fn default() -> Self {
14 Self {
15 executor: E::default(),
16 task_executor: None,
17 }
18 }
19}
20
21impl<E: Clone> Clone for ConfiguredExecutor<E> {
22 fn clone(&self) -> Self {
23 Self {
24 executor: self.executor.clone(),
25 task_executor: self.task_executor,
26 }
27 }
28}
29
30impl<E: Debug> Debug for ConfiguredExecutor<E> {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 f.debug_struct("ConfiguredExecutor")
33 .field("executor", &self.executor)
34 .field("task_executor", &self.task_executor)
35 .finish()
36 }
37}
38
39impl<E> ConfiguredExecutor<E> {
40 pub fn new(executor: E) -> Self {
41 Self {
42 executor,
43 task_executor: None,
44 }
45 }
46
47 pub fn with_task_executor(executor: E, task_executor: BuiltinExecutor) -> Self {
48 Self {
49 executor,
50 task_executor: Some(task_executor),
51 }
52 }
53
54 pub fn executor(&self) -> &E {
55 &self.executor
56 }
57
58 pub fn task_executor(&self) -> Option<BuiltinExecutor> {
59 self.task_executor
60 }
61
62 pub fn into_executor(self) -> E {
63 self.executor
64 }
65}
66
67impl<E: Executor> Executor for ConfiguredExecutor<E> {
68 fn runtime_type(&self) -> Option<&'static str> {
69 self.executor.runtime_type()
70 }
71
72 fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
73 where
74 F: Future + Send + 'static,
75 F::Output: Send + 'static,
76 {
77 self.executor.spawn(future)
78 }
79}
80
81impl<E: ExecutorTimeout> ExecutorTimeout for ConfiguredExecutor<E> {}
82impl<E: ExecutorBlocking> ExecutorBlocking for ConfiguredExecutor<E> {
83 fn spawn_blocking<F, R>(&self, f: F) -> JoinHandle<R>
84 where
85 F: FnOnce() -> R + Send + 'static,
86 R: Send + 'static,
87 {
88 self.executor.spawn_blocking(f)
89 }
90}
91
92impl<E: ExecutorBlockOn> ExecutorBlockOn for ConfiguredExecutor<E> {
93 fn block_on<F: Future>(&self, future: F) -> F::Output {
94 let _guard = self.task_executor.map(crate::task::set_executor);
95 self.executor.block_on(future)
96 }
97}