1 | //! Windows-specific style queries |
---|---|
2 | |
3 | #[cfg(windows)] |
4 | mod 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))] |
61 | mod windows_console { |
62 | #[inline] |
63 | pub(crate) fn enable_ansi_colors() -> Option<bool> { |
64 | None |
65 | } |
66 | } |
67 | |
68 | /// Enable ANSI escape codes ([`ENABLE_VIRTUAL_TERMINAL_PROCESSING`](https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences)) |
69 | /// |
70 | /// For non-windows systems, returns `None` |
71 | pub fn enable_ansi_colors() -> Option<bool> { |
72 | windows_console::enable_ansi_colors() |
73 | } |
74 | |
75 | /// Raw ENABLE_VIRTUAL_TERMINAL_PROCESSING on stdout/stderr |
76 | #[cfg(windows)] |
77 | pub fn enable_virtual_terminal_processing() -> std::io::Result<()> { |
78 | windows_console::enable_virtual_terminal_processing() |
79 | } |
80 |