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