#[cfg(windows)]
use windows::Win32::System::Console::{
GetConsoleMode, GetStdHandle, SetConsoleCP, SetConsoleMode, SetConsoleOutputCP, CONSOLE_MODE,
ENABLE_VIRTUAL_TERMINAL_PROCESSING, STD_OUTPUT_HANDLE,
};
#[cfg(windows)]
pub fn setup_windows_console() -> Result<(), String> {
unsafe {
SetConsoleCP(65001)
.map_err(|e| format!("Failed to set console input code page to UTF-8: {}", e))?;
if SetConsoleOutputCP(65001).is_err() {
return Err("Failed to set console output code page to UTF-8".to_string());
}
let handle = match GetStdHandle(STD_OUTPUT_HANDLE) {
Ok(h) => h,
Err(e) => return Err(format!("Failed to get stdout handle: {}", e)),
};
let mut mode = CONSOLE_MODE(0);
if GetConsoleMode(handle, &mut mode).is_ok() {
let new_mode = mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if SetConsoleMode(handle, new_mode).is_err() {
eprintln!(
"Warning: Could not enable virtual terminal processing. ANSI colors may not work."
);
}
}
}
Ok(())
}
#[cfg(not(windows))]
pub fn setup_windows_console() -> Result<(), String> {
Ok(())
}
#[cfg(windows)]
pub fn is_console_utf8() -> bool {
use windows::Win32::System::Console::GetConsoleOutputCP;
unsafe {
let cp = GetConsoleOutputCP();
cp == 65001 }
}
#[cfg(not(windows))]
pub fn is_console_utf8() -> bool {
true
}
#[cfg(windows)]
pub fn is_console_input_utf8() -> bool {
use windows::Win32::System::Console::GetConsoleCP;
unsafe {
let cp = GetConsoleCP();
cp == 65001 }
}
#[cfg(not(windows))]
pub fn is_console_input_utf8() -> bool {
true
}
#[cfg(windows)]
pub fn get_console_code_page() -> u32 {
use windows::Win32::System::Console::GetConsoleOutputCP;
unsafe { GetConsoleOutputCP() }
}
#[cfg(not(windows))]
pub fn get_console_code_page() -> u32 {
65001 }
#[cfg(windows)]
pub fn get_console_input_code_page() -> u32 {
use windows::Win32::System::Console::GetConsoleCP;
unsafe { GetConsoleCP() }
}
#[cfg(not(windows))]
pub fn get_console_input_code_page() -> u32 {
65001 }
pub fn code_page_name(code_page: u32) -> &'static str {
match code_page {
65001 => "UTF-8",
936 => "GBK (Simplified Chinese)",
950 => "Big5 (Traditional Chinese)",
932 => "Shift-JIS (Japanese)",
949 => "EUC-KR (Korean)",
437 => "OEM United States",
1252 => "Western European (Windows)",
_ => "Unknown",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_setup_console() {
let result = setup_windows_console();
assert!(result.is_ok());
}
#[test]
fn test_is_console_utf8() {
let _ = setup_windows_console();
#[cfg(windows)]
{
let is_utf8 = is_console_utf8();
let _ = is_utf8;
}
#[cfg(not(windows))]
{
assert!(is_console_utf8());
}
}
#[test]
fn test_code_page_names() {
assert_eq!(code_page_name(65001), "UTF-8");
assert_eq!(code_page_name(936), "GBK (Simplified Chinese)");
assert_eq!(code_page_name(950), "Big5 (Traditional Chinese)");
assert_eq!(code_page_name(12345), "Unknown");
}
#[test]
fn test_get_code_page() {
let cp = get_console_code_page();
#[cfg(windows)]
{
let _ = setup_windows_console();
let cp_after = get_console_code_page();
assert_eq!(cp_after, 65001);
}
#[cfg(not(windows))]
{
assert_eq!(cp, 65001);
}
}
}