output-vt100-rs/src/lib.rs

85 lines
2.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! # 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, youve 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 thats it! By calling it once, you have now activated PowerShells and
//! CMDs support for ANSIs 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();
}
}