diff --git a/src/string.rs b/src/string.rs index 37e0c3d..e91416b 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; +use std::string::String as StdString; use std::{slice, str}; #[cfg(feature = "serialize")] @@ -44,6 +46,28 @@ impl<'lua> String<'lua> { }) } + /// Converts this string to a [`Cow`]. + /// + /// Any non-Unicode sequences are replaced with [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD]. + /// + /// [U+FFFD]: std::char::REPLACEMENT_CHARACTER + /// + /// # Examples + /// + /// ``` + /// # use mlua::{Lua, Result}; + /// # fn main() -> Result<()> { + /// let lua = Lua::new(); + /// + /// let s = lua.create_string(b"test\xff")?; + /// assert_eq!(s.to_string_lossy(), "test\u{fffd}"); + /// # Ok(()) + /// # } + /// ``` + pub fn to_string_lossy(&self) -> Cow<'_, str> { + StdString::from_utf8_lossy(self.as_bytes()) + } + /// Get the bytes that make up this string. /// /// The returned slice will not contain the terminating nul byte, but will contain any nul diff --git a/tests/string.rs b/tests/string.rs index abe8aaa..5a6f8ea 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -39,6 +39,10 @@ fn string_views() -> Result<()> { let empty: String = globals.get("empty")?; assert_eq!(ok.to_str()?, "null bytes are valid utf-8, wh\0 knew?"); + assert_eq!( + ok.to_string_lossy(), + "null bytes are valid utf-8, wh\0 knew?" + ); assert_eq!( ok.as_bytes(), &b"null bytes are valid utf-8, wh\0 knew?"[..]