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