1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
macro_rules! ansi_sgr { ($func:ident, $value:expr) => { #[inline] pub fn $func(mut self) -> AnsiBuilder { self.0.0.push_str(concat!("\x1B[",$value, "m")); self.0 } }; } pub mod color; pub mod cursor; pub mod style; #[cfg(windows)] ::windows::include_bindings!(); #[cfg(windows)] pub fn enable_ansi_color() -> bool { use std::os::windows::io::AsRawHandle; use std::io::stdout; use Windows::Win32::System::SystemServices::HANDLE; use Windows::Win32::System::Console::{ CONSOLE_MODE, ENABLE_PROCESSED_OUTPUT, ENABLE_VIRTUAL_TERMINAL_PROCESSING, GetConsoleMode, SetConsoleMode, }; let std_out_handle = HANDLE(stdout().as_raw_handle() as isize); unsafe { let mut console_mode = CONSOLE_MODE::default(); if !GetConsoleMode(std_out_handle, &mut console_mode).as_bool() { return false } let is_ansi_enabled = (console_mode & ENABLE_PROCESSED_OUTPUT).0 != 0 && (console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING).0 != 0; if is_ansi_enabled { return true } if !SetConsoleMode( std_out_handle, console_mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING ).as_bool() { return false } true } } pub enum EraseMode { CursorToEnd = 0, CursorToBegin = 1, Screen = 2, Everything = 3, } pub enum ClearMode { CursorToEnd = 0, CursorToBegin = 1, EntireLine = 2, } pub struct AnsiBuilder(String); impl AnsiBuilder { pub fn new() -> Self { let val = String::with_capacity(40); Self(val) } pub fn erase_line(mut self, mode: ClearMode) -> Self { self.0.push_str(&format!("\x1B[{}K", mode as u8)); self } pub fn cursor(self) -> Cursor { Cursor(self) } pub fn color(self) -> Color { Color(self) } pub fn text(mut self, string: &str) -> Self { self.0.push_str(string); self } pub fn erase_in_display(mut self, mode: EraseMode) -> Self { self.0.push_str(&format!("\x1B[{}J", mode as u8)); self } pub fn print(mut self) -> Self { print!("{}", self.0); self.0.clear(); self } pub fn println(mut self) -> Self { println!("{}", self.0); self.0.clear(); self } pub fn reset_attributes(mut self) -> Self { self.0.push_str("\x1B[0m"); self } pub fn style(self) -> Style { Style(self) } } use color::Color; use cursor::Cursor; use style::Style;