diff options
Diffstat (limited to 'vendor/output_vt100/src/lib.rs')
-rw-r--r-- | vendor/output_vt100/src/lib.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/output_vt100/src/lib.rs b/vendor/output_vt100/src/lib.rs new file mode 100644 index 000000000..20338f1e5 --- /dev/null +++ b/vendor/output_vt100/src/lib.rs @@ -0,0 +1,84 @@ +//! # Output-VT100 +//! +//! When you write terminal-based crates, sometimes you might want to use the +//! standard ANSI escaped characters, to display some colors, to display text +//! as bold, italic or whatever. However, you’ve just discovered all your +//! pretty displays that worked like a charm on Linux and Mac look terrible +//! on Windows, because the escaped characters do not work. Rather, they are +//! not activated by default. Then you discover you have to do system calls to +//! Windows directly to activate them in order to get your beautiful text back. +//! What a pain! +//! And this is where this crate comes in action! Simply add it as a dependency +//! for your own crate, and use it like this: +//! ```rust +//! extern crate output_vt100; +//! +//! fn main() { +//! output_vt100::init(); +//! println!("\x1b[31mThis text is red!\x1b[0m"); +//! } +//! ``` +//! And that’s it! By calling it once, you have now activated PowerShell’s and +//! CMD’s support for ANSI’s escaped characters on your Windows builds! And +//! you can leave this line in your Unix builds too, it will simply do nothing. + +use std::fmt; + +#[derive(Debug)] +pub struct InitError; + +impl fmt::Display for InitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "output-vt100-rs: Could not initialize") + } +} + +impl std::error::Error for InitError {} + +#[cfg(windows)] +pub fn try_init() -> Result<(), InitError> { + use winapi::shared::minwindef::DWORD; + use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode}; + use winapi::um::processenv::GetStdHandle; + use winapi::um::winbase::STD_OUTPUT_HANDLE; + use winapi::um::wincon::{DISABLE_NEWLINE_AUTO_RETURN, ENABLE_VIRTUAL_TERMINAL_PROCESSING}; + + let console_out = unsafe { GetStdHandle(STD_OUTPUT_HANDLE) }; + + let mut state: DWORD = 0; + let mut ret: Result<(), _> = Ok(()); + unsafe { + if GetConsoleMode(console_out, &mut state) == 0 { + ret = Err(InitError); + } + if ret.is_ok() { + state |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + state &= !DISABLE_NEWLINE_AUTO_RETURN; + if SetConsoleMode(console_out, state) == 0 { + ret = Err(InitError); + } + } + } + return ret; +} + +#[cfg(windows)] +pub fn init() { + assert_eq!(try_init().is_ok(), true); +} + +#[cfg(not(windows))] +pub fn try_init() -> Result<(), InitError> { + Ok(()) +} + +#[cfg(not(windows))] +pub fn init() {} + +#[cfg(test)] +mod tests { + #[test] + fn activate_vt100() { + crate::init(); + } +} |