1#[cfg(windows)]
2mod windows_console {
3 use std::os::raw::c_void;
4
5 #[allow(non_camel_case_types)] type c_ulong = u32;
6 #[allow(non_camel_case_types)] type c_int = i32;
7 type DWORD = c_ulong;
8 type LPDWORD = *mut DWORD;
9 type HANDLE = *mut c_void;
10 type BOOL = c_int;
11
12 const ENABLE_VIRTUAL_TERMINAL_PROCESSING: DWORD = 0x0004;
13 const STD_OUTPUT_HANDLE: DWORD = 0xFFFFFFF5;
14 const STD_ERROR_HANDLE: DWORD = 0xFFFFFFF4;
15 const INVALID_HANDLE_VALUE: HANDLE = -1isize as HANDLE;
16 const FALSE: BOOL = 0;
17 const TRUE: BOOL = 1;
18
19 extern "system" {
21 fn GetStdHandle(nStdHandle: DWORD) -> HANDLE;
22 fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
23 fn SetConsoleMode(hConsoleHandle: HANDLE, dwMode: DWORD) -> BOOL;
24 }
25
26 unsafe fn get_handle(handle_num: DWORD) -> Result<HANDLE, ()> {
27 match GetStdHandle(handle_num) {
28 handle if handle == INVALID_HANDLE_VALUE => Err(()),
29 handle => Ok(handle)
30 }
31 }
32
33 unsafe fn enable_vt(handle: HANDLE) -> Result<(), ()> {
34 let mut dw_mode: DWORD = 0;
35 if GetConsoleMode(handle, &mut dw_mode) == FALSE {
36 return Err(());
37 }
38
39 dw_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
40 match SetConsoleMode(handle, dw_mode) {
41 result if result == TRUE => Ok(()),
42 _ => Err(())
43 }
44 }
45
46 unsafe fn enable_ascii_colors_raw() -> Result<bool, ()> {
47 let stdout_handle = get_handle(STD_OUTPUT_HANDLE)?;
48 let stderr_handle = get_handle(STD_ERROR_HANDLE)?;
49
50 enable_vt(stdout_handle)?;
51 if stdout_handle != stderr_handle {
52 enable_vt(stderr_handle)?;
53 }
54
55 Ok(true)
56 }
57
58 #[inline]
59 pub fn enable_ascii_colors() -> bool {
60 unsafe { enable_ascii_colors_raw().unwrap_or(false) }
61 }
62}
63
64#[cfg(not(windows))]
65mod windows_console {
66 pub fn enable_ascii_colors() -> bool { true }
67}
68
69pub use self::windows_console::enable_ascii_colors;