File tree Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Original file line number Diff line number Diff line change 1+ use parking_lot:: Mutex ;
2+
3+ use super :: MultiValue ;
14use std:: error:: Error as StdError ;
25use std:: fmt;
36use 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 }
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ use std::sync::Arc;
66use crate :: error:: { Error , Result } ;
77use crate :: state:: { ExtraData , RawLua } ;
88use crate :: util:: { self , get_internal_metatable, WrappedFailure } ;
9+ use crate :: IntoLuaMulti ;
910
1011pub ( 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
You can’t perform that action at this time.
0 commit comments