@@ -76,6 +76,17 @@ impl FromLua for String {
7676 message : Some ( "expected string or number" . to_string ( ) ) ,
7777 } )
7878 }
79+
80+ unsafe fn from_stack ( idx : c_int , lua : & RawLua ) -> Result < Self > {
81+ let state = lua. state ( ) ;
82+ let type_id = ffi:: lua_type ( state, idx) ;
83+ if type_id == ffi:: LUA_TSTRING {
84+ ffi:: lua_xpush ( state, lua. ref_thread ( ) , idx) ;
85+ return Ok ( String ( lua. pop_ref_thread ( ) ) ) ;
86+ }
87+ // Fallback to default
88+ Self :: from_lua ( lua. stack_value ( idx, Some ( type_id) ) , lua. lua ( ) )
89+ }
7990}
8091
8192impl IntoLua for Table {
@@ -385,7 +396,8 @@ impl FromLua for StdString {
385396 #[ inline]
386397 unsafe fn from_stack ( idx : c_int , lua : & RawLua ) -> Result < Self > {
387398 let state = lua. state ( ) ;
388- if ffi:: lua_type ( state, idx) == ffi:: LUA_TSTRING {
399+ let type_id = ffi:: lua_type ( state, idx) ;
400+ if type_id == ffi:: LUA_TSTRING {
389401 let mut size = 0 ;
390402 let data = ffi:: lua_tolstring ( state, idx, & mut size) ;
391403 let bytes = slice:: from_raw_parts ( data as * const u8 , size) ;
@@ -398,7 +410,7 @@ impl FromLua for StdString {
398410 } ) ;
399411 }
400412 // Fallback to default
401- Self :: from_lua ( lua. stack_value ( idx) , lua. lua ( ) )
413+ Self :: from_lua ( lua. stack_value ( idx, Some ( type_id ) ) , lua. lua ( ) )
402414 }
403415}
404416
@@ -536,9 +548,9 @@ impl FromLua for BString {
536548 mlua_assert ! ( !buf. is_null( ) , "invalid Luau buffer" ) ;
537549 Ok ( slice:: from_raw_parts ( buf as * const u8 , size) . into ( ) )
538550 }
539- _ => {
551+ type_id => {
540552 // Fallback to default
541- Self :: from_lua ( lua. stack_value ( idx) , lua. lua ( ) )
553+ Self :: from_lua ( lua. stack_value ( idx, Some ( type_id ) ) , lua. lua ( ) )
542554 }
543555 }
544556 }
@@ -622,6 +634,24 @@ macro_rules! lua_convert_int {
622634 message: Some ( "out of range" . to_owned( ) ) ,
623635 } )
624636 }
637+
638+ unsafe fn from_stack( idx: c_int, lua: & RawLua ) -> Result <Self > {
639+ let state = lua. state( ) ;
640+ let type_id = ffi:: lua_type( state, idx) ;
641+ if type_id == ffi:: LUA_TNUMBER {
642+ let mut ok = 0 ;
643+ let i = ffi:: lua_tointegerx( state, idx, & mut ok) ;
644+ if ok != 0 {
645+ return cast( i) . ok_or_else( || Error :: FromLuaConversionError {
646+ from: "integer" ,
647+ to: stringify!( $x) ,
648+ message: Some ( "out of range" . to_owned( ) ) ,
649+ } ) ;
650+ }
651+ }
652+ // Fallback to default
653+ Self :: from_lua( lua. stack_value( idx, Some ( type_id) ) , lua. lua( ) )
654+ }
625655 }
626656 } ;
627657}
@@ -672,6 +702,24 @@ macro_rules! lua_convert_float {
672702 } )
673703 } )
674704 }
705+
706+ unsafe fn from_stack( idx: c_int, lua: & RawLua ) -> Result <Self > {
707+ let state = lua. state( ) ;
708+ let type_id = ffi:: lua_type( state, idx) ;
709+ if type_id == ffi:: LUA_TNUMBER {
710+ let mut ok = 0 ;
711+ let i = ffi:: lua_tonumberx( state, idx, & mut ok) ;
712+ if ok != 0 {
713+ return cast( i) . ok_or_else( || Error :: FromLuaConversionError {
714+ from: "number" ,
715+ to: stringify!( $x) ,
716+ message: Some ( "out of range" . to_owned( ) ) ,
717+ } ) ;
718+ }
719+ }
720+ // Fallback to default
721+ Self :: from_lua( lua. stack_value( idx, Some ( type_id) ) , lua. lua( ) )
722+ }
675723 }
676724 } ;
677725}
@@ -893,10 +941,9 @@ impl<T: FromLua> FromLua for Option<T> {
893941
894942 #[ inline]
895943 unsafe fn from_stack ( idx : c_int , lua : & RawLua ) -> Result < Self > {
896- if ffi:: lua_isnil ( lua. state ( ) , idx) != 0 {
897- Ok ( None )
898- } else {
899- Ok ( Some ( T :: from_stack ( idx, lua) ?) )
944+ match ffi:: lua_type ( lua. state ( ) , idx) {
945+ ffi:: LUA_TNIL => Ok ( None ) ,
946+ _ => Ok ( Some ( T :: from_stack ( idx, lua) ?) ) ,
900947 }
901948 }
902949}
0 commit comments