Skip to content

Commit 8ce9826

Browse files
committed
Add yielding support.
1 parent cd4091f commit 8ce9826

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/error.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use parking_lot::Mutex;
2+
3+
use super::MultiValue;
14
use std::error::Error as StdError;
25
use std::fmt;
36
use std::io::Error as IoError;
@@ -205,6 +208,12 @@ pub enum Error {
205208
/// Underlying error.
206209
cause: Arc<Error>,
207210
},
211+
/// Yield.
212+
///
213+
/// Not an error.
214+
/// Returning `Err(Yielding(...))` from a Rust callback will yield the value as a Lua value.
215+
/// If it cannot yield, it will raise an error.
216+
Yielding(Arc<Mutex<MultiValue>>),
208217
}
209218

210219
/// A specialized `Result` type used by `mlua`'s API.
@@ -321,6 +330,9 @@ impl fmt::Display for Error {
321330
Error::WithContext { context, cause } => {
322331
writeln!(fmt, "{context}")?;
323332
write!(fmt, "{cause}")
333+
},
334+
Error::Yielding(_) => {
335+
write!(fmt, "yield across Rust/Lua boundary")
324336
}
325337
}
326338
}

src/state/util.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::sync::Arc;
66
use crate::error::{Error, Result};
77
use crate::state::{ExtraData, RawLua};
88
use crate::util::{self, get_internal_metatable, WrappedFailure};
9+
use crate::IntoLuaMulti;
910

1011
pub(super) struct StateGuard<'a>(&'a RawLua, *mut ffi::lua_State);
1112

@@ -107,7 +108,19 @@ where
107108
prealloc_failure.release(state, extra);
108109
r
109110
}
110-
Ok(Err(err)) => {
111+
Ok(Err(mut err)) => {
112+
if let Error::Yielding(tuple) = err {
113+
let raw = extra.as_ref().unwrap_unchecked().raw_lua();
114+
match Arc::into_inner(tuple).unwrap().into_inner().push_into_stack_multi(raw) {
115+
Ok(nargs) => {
116+
ffi::lua_yield(state, nargs);
117+
unreachable!();
118+
}
119+
Err(new_err) => {
120+
err = new_err;
121+
}
122+
}
123+
}
111124
let wrapped_error = prealloc_failure.r#use(state, extra);
112125

113126
// Build `CallbackError` with traceback

0 commit comments

Comments
 (0)