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