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}