Skip to main content

lua_std/
coroutine.rs

1//! The coroutine library.
2//!
3//! Coroutines are collaborative multithreading: each coroutine is an
4//! independent [`thread`] of execution that suspends
5//! itself explicitly with `coroutine.yield` and is resumed from
6//! the outside with [`resume`].
7//!
8//! ```lua
9//! local co = coroutine.create(function(a)
10//!   local b = coroutine.yield(a + 1)
11//!   return b * 2
12//! end)
13//! print(coroutine.resume(co, 1))   --> true   2
14//! print(coroutine.resume(co, 10))  --> true   20
15//! ```
16
17use crate::{any, boolean, function, option, thread, Repeatable};
18
19/// Closes the coroutine, i.e. closes all its pending to-be-closed
20/// variables and puts it in a dead state. The coroutine must be dead or
21/// suspended. Returns true on success, or false plus an error object.
22///
23/// # Examples
24///
25/// ```lua
26/// local co = coroutine.create(function() coroutine.yield() end)
27/// coroutine.resume(co)
28/// print(coroutine.close(co))     --> true
29/// print(coroutine.status(co))    --> dead
30/// ```
31pub fn close(co: thread) -> (boolean, option<any>) {
32    todo!()
33}
34
35/// Creates a new coroutine with body `f`, which must be a function.
36/// Returns the new coroutine, an object with type `"thread"`.
37///
38/// # Examples
39///
40/// ```lua
41/// local co = coroutine.create(function() end)
42/// print(co)          --> thread: 0x...
43/// print(type(co))    --> thread
44/// ```
45pub fn create(f: function) -> thread {
46    todo!()
47}
48
49/// Returns true when the running coroutine can yield — that is, when it
50/// is not the main coroutine and it is not inside a non-yieldable C
51/// function.
52///
53/// # Examples
54///
55/// ```lua
56/// print(coroutine.isyieldable())    --> false   (main coroutine)
57/// coroutine.wrap(function()
58///   print(coroutine.isyieldable())  --> true
59/// end)()
60/// ```
61pub fn isyieldable() -> boolean {
62    todo!()
63}
64
65/// Starts or continues the execution of the coroutine `co`. On the first
66/// resume, the values are passed as arguments to the body function; on
67/// later resumes, they become the results of the pending
68/// `coroutine.yield`.
69///
70/// Returns true plus any values yielded or returned by `co`, or false
71/// plus an error message if the coroutine raised an error.
72///
73/// # Examples
74///
75/// ```lua
76/// local co = coroutine.create(function(x, y) return x + y end)
77/// print(coroutine.resume(co, 3, 4))    --> true   7
78/// print(coroutine.resume(co))          --> false   cannot resume dead coroutine
79/// ```
80pub fn resume(co: thread, values: Repeatable<any>) -> (boolean, Repeatable<any>) {
81    todo!()
82}
83
84/// Returns the running coroutine plus a boolean that is true when the
85/// running coroutine is the main one.
86///
87/// # Examples
88///
89/// ```lua
90/// local co, ismain = coroutine.running()
91/// print(ismain)    --> true   (called from the main coroutine)
92/// ```
93pub fn running() -> (thread, boolean) {
94    todo!()
95}
96
97/// Returns the status of the coroutine `co`, as a string: `"running"`,
98/// `"suspended"`, `"normal"` (active but not running), or `"dead"`.
99///
100/// # Examples
101///
102/// ```lua
103/// local co = coroutine.create(function() coroutine.yield() end)
104/// print(coroutine.status(co))    --> suspended
105/// coroutine.resume(co)
106/// print(coroutine.status(co))    --> suspended   (stopped at the yield)
107/// coroutine.resume(co)
108/// print(coroutine.status(co))    --> dead
109/// ```
110pub fn status(co: thread) -> crate::string {
111    todo!()
112}
113
114/// Creates a new coroutine with body `f` and returns a function that
115/// resumes it each time it is called. Arguments to that function pass
116/// into the coroutine, and its yielded values come back as results —
117/// but unlike [`resume`], errors are propagated to the caller.
118///
119/// # Examples
120///
121/// ```lua
122/// local gen = coroutine.wrap(function()
123///   for i = 1, 3 do coroutine.yield(i) end
124/// end)
125/// print(gen(), gen(), gen())    --> 1   2   3
126/// ```
127pub fn wrap(f: function) -> function {
128    todo!()
129}
130
131/// Suspends the execution of the calling coroutine. Any arguments are
132/// returned as extra results by the [`resume`] that woke the coroutine
133/// up; symmetrically, `yield` returns the extra values passed to the
134/// next [`resume`].
135///
136/// # Examples
137///
138/// ```lua
139/// local co = coroutine.create(function(a)
140///   local b = coroutine.yield(a * 2)   -- b comes from the next resume
141///   return a + b
142/// end)
143/// print(coroutine.resume(co, 10))    --> true   20
144/// print(coroutine.resume(co, 5))     --> true   15
145/// ```
146pub fn r#yield(values: Repeatable<any>) -> Repeatable<any> {
147    todo!()
148}