Skip to main content

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}