1#[cfg(windows)]
4mod windows_console {
5 use std::os::windows::io::AsRawHandle;
6 use std::os::windows::io::RawHandle;
7
8 use windows_sys::Win32::Foundation::HANDLE;
9 use windows_sys::Win32::System::Console::CONSOLE_MODE;
10 use windows_sys::Win32::System::Console::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
11
12 fn enable_vt(handle: RawHandle) -> std::io::Result<()> {
13 unsafe {
14 let handle: HANDLE = std::mem::transmute(handle);
15 if handle.is_null() {
16 return Err(std::io::Error::new(
17 std::io::ErrorKind::BrokenPipe,
18 "console is detached",
19 ));
20 }
21
22 let mut dwmode: CONSOLE_MODE = 0;
23 if windows_sys::Win32::System::Console::GetConsoleMode(handle, &mut dwmode) == 0 {
24 return Err(std::io::Error::last_os_error());
25 }
26
27 dwmode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
28 if windows_sys::Win32::System::Console::SetConsoleMode(handle, dwmode) == 0 {
29 return Err(std::io::Error::last_os_error());
30 }
31
32 Ok(())
33 }
34 }
35
36 pub fn enable_virtual_terminal_processing() -> std::io::Result<()> {
37 let stdout = std::io::stdout();
38 let stdout_handle = stdout.as_raw_handle();
39 let stderr = std::io::stderr();
40 let stderr_handle = stderr.as_raw_handle();
41
42 enable_vt(stdout_handle)?;
43 if stdout_handle != stderr_handle {
44 enable_vt(stderr_handle)?;
45 }
46
47 Ok(())
48 }
49
50 #[inline]
51 pub(crate) fn enable_ansi_colors() -> Option<bool> {
52 Some(
53 enable_virtual_terminal_processing()
54 .map(|_| true)
55 .unwrap_or(false),
56 )
57 }
58}
59
60#[cfg(not(windows))]
61mod windows_console {
62 #[inline]
63 pub(crate) fn enable_ansi_colors() -> Option<bool> {
64 None
65 }
66}
67
68pub fn enable_ansi_colors() -> Option<bool> {
72 windows_console::enable_ansi_colors()
73}
74
75#[cfg(windows)]
77pub fn enable_virtual_terminal_processing() -> std::io::Result<()> {
78 windows_console::enable_virtual_terminal_processing()
79}