qubit_executor/executor/executor.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use qubit_function::{
11 Callable,
12 Runnable,
13};
14
15/// Executes fallible one-time tasks according to an implementation-defined strategy.
16///
17/// `Executor` models an execution strategy, not a managed task service. An
18/// executor may run a task immediately, retry it, delay it, schedule it on
19/// another runtime, or return a handle that represents work running elsewhere.
20/// The associated [`Self::Execution`] type describes how this executor exposes
21/// the result of a single execution.
22///
23pub trait Executor: Send + Sync {
24 /// The result carrier returned for one execution.
25 ///
26 /// Implementations choose the carrier that matches their execution model.
27 /// For example, a direct executor can use `Result<R, E>`, while a threaded
28 /// executor can use a task handle and a future-backed executor can use a
29 /// future.
30 type Execution<R, E>
31 where
32 R: Send + 'static,
33 E: std::fmt::Display + Send + 'static;
34
35 /// Executes a runnable task and returns this executor's result carrier.
36 ///
37 /// This is the unit-returning counterpart of [`Self::call`]. The returned
38 /// carrier reports the runnable's `Result<(), E>` according to the concrete
39 /// executor's execution model.
40 ///
41 /// # Parameters
42 ///
43 /// * `task` - The fallible action to execute.
44 ///
45 /// # Returns
46 ///
47 /// The execution carrier for the submitted runnable.
48 #[inline]
49 fn execute<T, E>(&self, task: T) -> Self::Execution<(), E>
50 where
51 T: Runnable<E> + Send + 'static,
52 E: std::fmt::Display + Send + 'static,
53 {
54 let mut task = task;
55 self.call(move || task.run())
56 }
57
58 /// Executes a callable task and returns this executor's result carrier.
59 ///
60 /// # Parameters
61 ///
62 /// * `task` - The fallible computation to execute.
63 ///
64 /// # Returns
65 ///
66 /// The execution carrier for the submitted callable. Its exact behavior is
67 /// defined by the concrete executor.
68 fn call<C, R, E>(&self, task: C) -> Self::Execution<R, E>
69 where
70 C: Callable<R, E> + Send + 'static,
71 R: Send + 'static,
72 E: std::fmt::Display + Send + 'static;
73}