1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Async task handle — a cancellable [`Future`] for a single Lua operation.
//!
//! An [`AsyncTask`] is returned by [`AsyncIsle::spawn_eval`](crate::AsyncIsle::spawn_eval),
//! [`AsyncIsle::spawn_call`](crate::AsyncIsle::spawn_call), and
//! [`AsyncIsle::spawn_exec`](crate::AsyncIsle::spawn_exec).
//!
//! It implements [`Future`] so it can be `.await`ed directly.
use crateIsleError;
use crateCancelToken;
use Future;
use Pin;
use ;
/// Async handle to a pending Lua operation.
///
/// Implements [`Future`] — `.await` it to get the result.
///
/// # Type parameter `T`
///
/// `AsyncTask` is generic over its output type `T`, following the
/// established Rust async ecosystem convention
/// ([`tokio::task::JoinHandle<T>`][tokio-jh],
/// [`async_task::Task<T>`][async-task],
/// [`async_std::task::JoinHandle<T>`][async-std-jh]).
///
/// The default `T = String` matches the built-in `eval`/`call`/`exec`
/// methods which return `String`. The generic parameter allows
/// downstream code to construct `AsyncTask<T>` with custom result
/// types when wrapping or extending the API.
///
/// [tokio-jh]: https://docs.rs/tokio/latest/tokio/task/struct.JoinHandle.html
/// [async-task]: https://docs.rs/async-task/latest/async_task/struct.Task.html
/// [async-std-jh]: https://docs.rs/async-std/latest/async_std/task/struct.JoinHandle.html
///
/// # Cancellation
///
/// Call [`cancel()`](AsyncTask::cancel) or clone the
/// [`cancel_token()`](AsyncTask::cancel_token) before awaiting:
///
/// ```rust
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use mlua_isle::AsyncIsle;
/// use std::time::Duration;
///
/// let (isle, driver) = AsyncIsle::spawn(|_lua| Ok(())).await?;
/// let task = isle.spawn_eval("while true do end");
/// let token = task.cancel_token().clone();
/// tokio::spawn(async move {
/// tokio::time::sleep(Duration::from_millis(100)).await;
/// token.cancel();
/// });
/// let result = task.await; // Err(Cancelled)
/// assert!(result.is_err());
/// driver.shutdown().await?;
/// # Ok(())
/// # }
/// ```