anstyle_query/
windows.rs

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`](https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences))
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}