mlua_isle/task.rs
1//! Task handle — a cancellable future for a single Lua operation.
2//!
3//! A [`Task`] is returned by [`Isle::spawn_eval`], [`Isle::spawn_call`],
4//! and [`Isle::spawn_exec`].
5//! It provides a [`CancelToken`] for interruption and a blocking
6//! [`wait`](Task::wait) method to collect the result.
7
8use crate::error::IsleError;
9use crate::hook::CancelToken;
10use std::sync::mpsc;
11
12/// Handle to a pending Lua operation.
13///
14/// The operation runs on the Lua thread. The caller can:
15/// - [`wait`](Task::wait) for the result (blocking).
16/// - [`cancel`](Task::cancel) the operation.
17/// - [`try_recv`](Task::try_recv) to poll without blocking.
18pub struct Task<T = String> {
19 rx: mpsc::Receiver<Result<T, IsleError>>,
20 cancel: CancelToken,
21}
22
23impl<T> Task<T> {
24 pub(crate) fn new(rx: mpsc::Receiver<Result<T, IsleError>>, cancel: CancelToken) -> Self {
25 Self { rx, cancel }
26 }
27
28 /// Block until the result is available.
29 pub fn wait(self) -> Result<T, IsleError> {
30 self.rx
31 .recv()
32 .map_err(|e| IsleError::RecvFailed(e.to_string()))?
33 }
34
35 /// Cancel the operation.
36 ///
37 /// This signals the Lua debug hook to interrupt execution.
38 /// The task will eventually return [`IsleError::Cancelled`].
39 pub fn cancel(&self) {
40 self.cancel.cancel();
41 }
42
43 /// Non-blocking poll for the result.
44 pub fn try_recv(&self) -> Option<Result<T, IsleError>> {
45 self.rx.try_recv().ok()
46 }
47
48 /// Access the cancel token (e.g. to share with other code).
49 pub fn cancel_token(&self) -> &CancelToken {
50 &self.cancel
51 }
52}