ansi_builder/
lib.rs

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;