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