diff --git a/crates/libs/windows/src/core/bindings.rs b/crates/libs/windows/src/core/bindings.rs index d1eed5174f..513a2f7f80 100644 --- a/crates/libs/windows/src/core/bindings.rs +++ b/crates/libs/windows/src/core/bindings.rs @@ -32,6 +32,7 @@ pub const FORMAT_MESSAGE_FROM_SYSTEM: u32 = 4096; pub const FORMAT_MESSAGE_IGNORE_INSERTS: u32 = 512; pub const AGILEREFERENCE_DEFAULT: i32 = 0; +pub const ERROR_NO_UNICODE_TRANSLATION: u32 = 1113u32; pub const CLASS_E_CLASSNOTAVAILABLE: HRESULT = HRESULT(-2147221231i32); pub const CO_E_NOTINITIALIZED: HRESULT = HRESULT(-2147221008i32); pub const E_NOINTERFACE: HRESULT = HRESULT(-2147467262i32); diff --git a/crates/libs/windows/src/core/error.rs b/crates/libs/windows/src/core/error.rs index 8fb48e4770..37474934c3 100644 --- a/crates/libs/windows/src/core/error.rs +++ b/crates/libs/windows/src/core/error.rs @@ -81,6 +81,18 @@ impl std::convert::From for std::io::Error { } } +impl std::convert::From for Error { + fn from(_: std::string::FromUtf16Error) -> Self { + Self { code: HRESULT::from_win32(ERROR_NO_UNICODE_TRANSLATION), info: None } + } +} + +impl std::convert::From for Error { + fn from(_: std::string::FromUtf8Error) -> Self { + Self { code: HRESULT::from_win32(ERROR_NO_UNICODE_TRANSLATION), info: None } + } +} + // Unfortunately this is needed to make types line up. The Rust type system does // not know the `Infallible` can never be constructed. This code needs to be here // to satesify the type checker but it will never be run. Once `!` is stabilizied diff --git a/crates/tests/core/tests/hstrings.rs b/crates/tests/core/tests/hstring.rs similarity index 100% rename from crates/tests/core/tests/hstrings.rs rename to crates/tests/core/tests/hstring.rs diff --git a/crates/tests/core/tests/pcstr.rs b/crates/tests/core/tests/pcstr.rs new file mode 100644 index 0000000000..073097f34f --- /dev/null +++ b/crates/tests/core/tests/pcstr.rs @@ -0,0 +1,17 @@ +use windows::{core::*, Win32::Foundation::*}; + +#[test] +fn test() -> Result<()> { + let p: PCSTR = s!("hello"); + let s: String = unsafe { p.to_string()? }; + assert_eq!("hello", s); + assert_eq!("hello", format!("{}", unsafe { p.display() })); + + let invalid = &[0xc0, 0x80]; + let p = PCSTR::from_raw(invalid.as_ptr()); + let e: Error = unsafe { p.to_string().unwrap_err().into() }; + assert_eq!(e.code(), ERROR_NO_UNICODE_TRANSLATION.into()); + assert_eq!(e.message(), "No mapping for the Unicode character exists in the target multi-byte code page."); + + Ok(()) +} diff --git a/crates/tests/core/tests/pcwstr.rs b/crates/tests/core/tests/pcwstr.rs new file mode 100644 index 0000000000..fd6015c00e --- /dev/null +++ b/crates/tests/core/tests/pcwstr.rs @@ -0,0 +1,18 @@ +use windows::{core::*, Win32::Foundation::*}; + +#[test] +fn test() -> Result<()> { + // `w!` returns a `&HSTRING` so `into()` is needed to convert it to a `PCWSTR` + let p: PCWSTR = w!("hello").into(); + let s: String = unsafe { p.to_string()? }; + assert_eq!("hello", s); + assert_eq!("hello", format!("{}", unsafe { p.display() })); + + let invalid = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; + let p = PCWSTR::from_raw(invalid.as_ptr()); + let e: Error = unsafe { p.to_string().unwrap_err().into() }; + assert_eq!(e.code(), ERROR_NO_UNICODE_TRANSLATION.into()); + assert_eq!(e.message(), "No mapping for the Unicode character exists in the target multi-byte code page."); + + Ok(()) +} diff --git a/crates/tests/core/tests/pstr.rs b/crates/tests/core/tests/pstr.rs new file mode 100644 index 0000000000..ed7fb3f21a --- /dev/null +++ b/crates/tests/core/tests/pstr.rs @@ -0,0 +1,17 @@ +use windows::{core::*, Win32::Foundation::*}; + +#[test] +fn test() -> Result<()> { + let p = PSTR::from_raw(s!("hello").as_ptr() as *mut _); + let s: String = unsafe { p.to_string()? }; + assert_eq!("hello", s); + assert_eq!("hello", format!("{}", unsafe { p.display() })); + + let invalid = &mut [0xc0, 0x80]; + let p = PSTR::from_raw(invalid.as_mut_ptr()); + let e: Error = unsafe { p.to_string().unwrap_err().into() }; + assert_eq!(e.code(), ERROR_NO_UNICODE_TRANSLATION.into()); + assert_eq!(e.message(), "No mapping for the Unicode character exists in the target multi-byte code page."); + + Ok(()) +} diff --git a/crates/tests/core/tests/pwstr.rs b/crates/tests/core/tests/pwstr.rs new file mode 100644 index 0000000000..a1aa1cb5d5 --- /dev/null +++ b/crates/tests/core/tests/pwstr.rs @@ -0,0 +1,17 @@ +use windows::{core::*, Win32::Foundation::*}; + +#[test] +fn test() -> Result<()> { + let p = PWSTR::from_raw(w!("hello").as_ptr() as *mut _); + let s: String = unsafe { p.to_string()? }; + assert_eq!("hello", s); + assert_eq!("hello", format!("{}", unsafe { p.display() })); + + let invalid = &mut [0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; + let p = PWSTR::from_raw(invalid.as_mut_ptr()); + let e: Error = unsafe { p.to_string().unwrap_err().into() }; + assert_eq!(e.code(), ERROR_NO_UNICODE_TRANSLATION.into()); + assert_eq!(e.message(), "No mapping for the Unicode character exists in the target multi-byte code page."); + + Ok(()) +}