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::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
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`
71pub 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)]
77pub fn enable_virtual_terminal_processing() -> std::io::Result<()> {
78    windows_console::enable_virtual_terminal_processing()
79}