Skip to content

Commit

Permalink
Add yielding support.
Browse files Browse the repository at this point in the history
  • Loading branch information
RadiantUwU committed Jan 25, 2025
1 parent cd4091f commit 1feedb4
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ pub enum Error {
/// Underlying error.
cause: Arc<Error>,
},
/// Yield.
///
/// Not an error.
/// Returning `Err(Yielding(...))` from a Rust callback will yield the value as a Lua value.
/// If it cannot yield, it will raise an error.
Yielding(MultiValue),
}

/// A specialized `Result` type used by `mlua`'s API.
Expand Down Expand Up @@ -321,6 +327,9 @@ impl fmt::Display for Error {
Error::WithContext { context, cause } => {
writeln!(fmt, "{context}")?;
write!(fmt, "{cause}")
},
Error::Yielding(_) => {
write!(fmt, "yield across Rust/Lua boundary")
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/state/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::sync::Arc;
use crate::error::{Error, Result};
use crate::state::{ExtraData, RawLua};
use crate::util::{self, get_internal_metatable, WrappedFailure};
use crate::IntoLuaMulti;

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

Expand Down Expand Up @@ -107,7 +108,14 @@ where
prealloc_failure.release(state, extra);
r
}
Ok(Err(err)) => {
Ok(Err(mut err)) => {
if let Error::Yielding(tuple) = err {
let raw = extra.as_ref().unwrap_unchecked().raw_lua();
match tuple.push_into_stack_multi(lua) {
Ok(nargs) => ffi::lua_yield(state, nargs),
Err(new_err) => err = new_err,
}
}
let wrapped_error = prealloc_failure.r#use(state, extra);

// Build `CallbackError` with traceback
Expand Down

0 comments on commit 1feedb4

Please sign in to comment.