use crate::output::TerminalOutput;
use std::io::{self, Write};
use std::sync::Arc;
#[cfg(windows)]
use crate::sys::winapi::ansi::set_virtual_terminal_processing;
#[cfg(windows)]
pub fn get_module<T>(winapi_impl: T, ansi_impl: T) -> Option<T> {
let supports_ansi = is_specific_term();
match supports_ansi {
true => {
return Some(ansi_impl);
}
false => {
match set_virtual_terminal_processing(true) {
Ok(_) => {
return Some(ansi_impl);
}
Err(_) => {
return Some(winapi_impl);
}
}
}
}
}
pub fn write(stdout: &Option<&Arc<TerminalOutput>>, string: String) -> io::Result<usize> {
match stdout {
None => {
print!("{}", string.as_str());
match io::stdout().flush() {
Ok(_) => Ok(string.len()),
Err(e) => Err(e),
}
}
Some(output) => output.write_string(string),
}
}
pub fn write_str(stdout: &Option<&Arc<TerminalOutput>>, string: &str) -> io::Result<usize> {
match stdout {
None => match io::stdout().flush() {
Ok(_) => {
write!(io::stdout(), "{}", string)?;
Ok(string.len())
}
Err(e) => Err(e),
},
Some(output) => output.write_str(string),
}
}
fn is_specific_term() -> bool {
const TERMS: [&'static str; 15] = [
"xterm", "rxvt", "eterm", "screen", "tmux", "vt100", "vt102", "vt220", "vt320", "ansi", "scoansi", "cygwin", "linux", "konsole", "bvterm", ];
match std::env::var("TERM") {
Ok(val) => val != "dumb" || TERMS.contains(&val.as_str()),
Err(_) => false,
}
}