diff options
-rw-r--r-- | src/lua.rs | 26 | ||||
-rw-r--r-- | src/types.rs | 7 | ||||
-rw-r--r-- | tests/tests.rs | 13 |
3 files changed, 27 insertions, 19 deletions
@@ -1027,7 +1027,7 @@ impl Lua { #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))] pub fn set_warning_function<F>(&self, callback: F) where - F: 'static + MaybeSend + Fn(&Lua, &CStr, bool) -> Result<()>, + F: Fn(&Lua, &str, bool) -> Result<()> + MaybeSend + 'static, { unsafe extern "C" fn warn_proc(ud: *mut c_void, msg: *const c_char, tocont: c_int) { let extra = ud as *mut ExtraData; @@ -1037,8 +1037,8 @@ impl Lua { (*extra).warn_callback.as_ref(), "no warning callback set in warn_proc" ); - let msg = CStr::from_ptr(msg); - cb(lua, msg, tocont != 0) + let msg = std::string::String::from_utf8_lossy(CStr::from_ptr(msg).to_bytes()); + cb(lua, &msg, tocont != 0) }); } @@ -1065,15 +1065,25 @@ impl Lua { /// Emits a warning with the given message. /// - /// A message in a call with `tocont` set to `true` should be continued in another call to this function. + /// A message in a call with `incomplete` set to `true` should be continued in + /// another call to this function. /// /// Requires `feature = "lua54"` #[cfg(feature = "lua54")] #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))] - pub fn warning<S: Into<Vec<u8>>>(&self, msg: S, tocont: bool) -> Result<()> { - let msg = CString::new(msg).map_err(|err| Error::RuntimeError(err.to_string()))?; - unsafe { ffi::lua_warning(self.state(), msg.as_ptr(), tocont as c_int) }; - Ok(()) + pub fn warning(&self, msg: impl AsRef<str>, incomplete: bool) { + let msg = msg.as_ref(); + let mut bytes = vec![0; msg.len() + 1]; + bytes[..msg.len()].copy_from_slice(msg.as_bytes()); + let real_len = bytes.iter().position(|&c| c == 0).unwrap(); + bytes.truncate(real_len); + unsafe { + ffi::lua_warning( + self.state(), + bytes.as_ptr() as *const c_char, + incomplete as c_int, + ); + } } /// Gets information about the interpreter runtime stack. diff --git a/src/types.rs b/src/types.rs index 25f3bc2..7dd874a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,9 +8,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::{fmt, mem, ptr}; -#[cfg(feature = "lua54")] -use std::ffi::CStr; - use rustc_hash::FxHashMap; #[cfg(feature = "async")] @@ -78,10 +75,10 @@ pub(crate) type InterruptCallback = Arc<dyn Fn(&Lua) -> Result<VmState> + Send>; pub(crate) type InterruptCallback = Arc<dyn Fn(&Lua) -> Result<VmState>>; #[cfg(all(feature = "send", feature = "lua54"))] -pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &CStr, bool) -> Result<()> + Send>; +pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()> + Send>; #[cfg(all(not(feature = "send"), feature = "lua54"))] -pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &CStr, bool) -> Result<()>>; +pub(crate) type WarnCallback = Box<dyn Fn(&Lua, &str, bool) -> Result<()>>; #[cfg(feature = "send")] pub trait MaybeSend: Send {} diff --git a/tests/tests.rs b/tests/tests.rs index a60d7b8..bd0eee2 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1278,20 +1278,20 @@ fn test_warnings() -> Result<()> { let lua = Lua::new(); lua.set_app_data::<Vec<(StdString, bool)>>(Vec::new()); - lua.set_warning_function(|lua, msg, tocont| { - let msg = msg.to_string_lossy().to_string(); + lua.set_warning_function(|lua, msg, incomplete| { lua.app_data_mut::<Vec<(StdString, bool)>>() .unwrap() - .push((msg, tocont)); + .push((msg.to_string(), incomplete)); Ok(()) }); - lua.warning("native warning ...", true)?; - lua.warning("finish", false)?; + lua.warning("native warning ...", true); + lua.warning("finish", false); + lua.warning("\0", false); lua.load(r#"warn("lua warning", "continue")"#).exec()?; lua.remove_warning_function(); - lua.warning("one more warning", false)?; + lua.warning("one more warning", false); let messages = lua.app_data_ref::<Vec<(StdString, bool)>>().unwrap(); assert_eq!( @@ -1299,6 +1299,7 @@ fn test_warnings() -> Result<()> { vec![ ("native warning ...".to_string(), true), ("finish".to_string(), false), + ("".to_string(), false), ("lua warning".to_string(), true), ("continue".to_string(), false), ] |