File tree 2 files changed +26
-1
lines changed
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 ;
1
4
use std:: error:: Error as StdError ;
2
5
use std:: fmt;
3
6
use std:: io:: Error as IoError ;
@@ -205,6 +208,12 @@ pub enum Error {
205
208
/// Underlying error.
206
209
cause : Arc < Error > ,
207
210
} ,
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 > > ) ,
208
217
}
209
218
210
219
/// A specialized `Result` type used by `mlua`'s API.
@@ -321,6 +330,9 @@ impl fmt::Display for Error {
321
330
Error :: WithContext { context, cause } => {
322
331
writeln ! ( fmt, "{context}" ) ?;
323
332
write ! ( fmt, "{cause}" )
333
+ } ,
334
+ Error :: Yielding ( _) => {
335
+ write ! ( fmt, "yield across Rust/Lua boundary" )
324
336
}
325
337
}
326
338
}
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ use std::sync::Arc;
6
6
use crate :: error:: { Error , Result } ;
7
7
use crate :: state:: { ExtraData , RawLua } ;
8
8
use crate :: util:: { self , get_internal_metatable, WrappedFailure } ;
9
+ use crate :: IntoLuaMulti ;
9
10
10
11
pub ( super ) struct StateGuard < ' a > ( & ' a RawLua , * mut ffi:: lua_State ) ;
11
12
@@ -107,7 +108,19 @@ where
107
108
prealloc_failure. release ( state, extra) ;
108
109
r
109
110
}
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
+ }
111
124
let wrapped_error = prealloc_failure. r#use ( state, extra) ;
112
125
113
126
// Build `CallbackError` with traceback
You can’t perform that action at this time.
0 commit comments