diff --git a/Cargo.toml b/Cargo.toml index d27efa1..0e28782 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,4 @@ serde = { version = "1", features = ["derive"] } serde_json = "1.0.140" [target.'cfg(windows)'.dependencies] -windows-sys = { version = "0", features = ["Win32_Globalization"] } +windows-sys = { version = "0", features = ["Win32_Globalization", "Win32_System_Diagnostics_Debug"] } diff --git a/src/utils/encoding.rs b/src/utils/encoding.rs index 1a19758..d1778da 100644 --- a/src/utils/encoding.rs +++ b/src/utils/encoding.rs @@ -102,3 +102,26 @@ fn test_decode_to_string() { "中文".to_string() ); } + +#[test] +fn test_encode_string() { + assert_eq!( + encode_string(Encoding::Utf8, "中文测试").unwrap(), + vec![228, 184, 173, 230, 150, 135, 230, 181, 139, 232, 175, 149] + ); + assert_eq!( + encode_string(Encoding::Cp932, "きゃべつそふと").unwrap(), + vec![ + 130, 171, 130, 225, 130, 215, 130, 194, 130, 187, 130, 211, 130, 198 + ] + ); + assert_eq!( + encode_string(Encoding::Gb2312, "中文").unwrap(), + vec![214, 208, 206, 196] + ); + #[cfg(windows)] + assert_eq!( + encode_string(Encoding::CodePage(936), "中文").unwrap(), + vec![214, 208, 206, 196] + ); +} diff --git a/src/utils/encoding_win.rs b/src/utils/encoding_win.rs index 094f076..5fe75f5 100644 --- a/src/utils/encoding_win.rs +++ b/src/utils/encoding_win.rs @@ -2,6 +2,9 @@ use windows_sys::Win32::Foundation::GetLastError; use windows_sys::Win32::Globalization::{ MB_ERR_INVALID_CHARS, MultiByteToWideChar, WideCharToMultiByte, }; +use windows_sys::Win32::System::Diagnostics::Debug::{ + FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessageW, +}; #[derive(Debug)] pub struct WinError { @@ -23,7 +26,24 @@ impl std::error::Error for WinError {} impl std::fmt::Display for WinError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Windows error code: {}", self.code) + let mut buffer = [0u16; 256]; + let len = unsafe { + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + std::ptr::null(), + self.code, + 0, + buffer.as_mut_ptr(), + buffer.len() as u32, + std::ptr::null_mut(), + ) + }; + if len == 0 { + write!(f, "Unknown error code: 0x{:08X}", self.code) + } else { + let message = String::from_utf16_lossy(&buffer[..len as usize]); + write!(f, "{} (0x{:08X})", message.trim(), self.code) + } } } @@ -121,3 +141,21 @@ fn test_decode_to_string() { "中文".to_string() ); } + +#[test] +fn test_encode_string() { + assert_eq!( + encode_string(65001, "中文测试").unwrap(), + vec![228, 184, 173, 230, 150, 135, 230, 181, 139, 232, 175, 149] + ); + assert_eq!( + encode_string(932, "きゃべつそふと").unwrap(), + vec![ + 130, 171, 130, 225, 130, 215, 130, 194, 130, 187, 130, 211, 130, 198 + ] + ); + assert_eq!( + encode_string(936, "中文").unwrap(), + vec![214, 208, 206, 196] + ); +}