Skip to content

Commit 1feedb4

Browse files
committed
Add yielding support.
1 parent cd4091f commit 1feedb4

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

src/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ pub enum Error {
205205
/// Underlying error.
206206
cause: Arc<Error>,
207207
},
208+
/// Yield.
209+
///
210+
/// Not an error.
211+
/// Returning `Err(Yielding(...))` from a Rust callback will yield the value as a Lua value.
212+
/// If it cannot yield, it will raise an error.
213+
Yielding(MultiValue),
208214
}
209215

210216
/// A specialized `Result` type used by `mlua`'s API.
@@ -321,6 +327,9 @@ impl fmt::Display for Error {
321327
Error::WithContext { context, cause } => {
322328
writeln!(fmt, "{context}")?;
323329
write!(fmt, "{cause}")
330+
},
331+
Error::Yielding(_) => {
332+
write!(fmt, "yield across Rust/Lua boundary")
324333
}
325334
}
326335
}

src/state/util.rs

Lines changed: 9 additions & 1 deletion
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,14 @@ 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 tuple.push_into_stack_multi(lua) {
115+
Ok(nargs) => ffi::lua_yield(state, nargs),
116+
Err(new_err) => err = new_err,
117+
}
118+
}
111119
let wrapped_error = prealloc_failure.r#use(state, extra);
112120

113121
// Build `CallbackError` with traceback

0 commit comments

Comments
 (0)