use std::io;
use super::*;
use crate::{Color, ITerminalColor};
use crossterm_utils::{Result, TerminalOutput};
#[cfg(windows)]
use crossterm_utils::get_module;
use std::sync::Arc;
pub struct TerminalColor<'stdout> {
color: Box<ITerminalColor + Sync + Send>,
stdout: Option<&'stdout Arc<TerminalOutput>>,
}
impl<'stdout> TerminalColor<'stdout> {
pub fn new() -> TerminalColor<'stdout> {
#[cfg(target_os = "windows")]
let color = get_module::<Box<ITerminalColor + Sync + Send>>(
Box::from(WinApiColor::new()),
Box::from(AnsiColor::new()),
)
.expect("could not extract module");
#[cfg(not(target_os = "windows"))]
let color = Box::from(AnsiColor::new()) as Box<ITerminalColor + Sync + Send>;
TerminalColor {
color,
stdout: None,
}
}
pub fn from_output(stdout: &'stdout Arc<TerminalOutput>) -> TerminalColor<'stdout> {
#[cfg(target_os = "windows")]
let color = get_module::<Box<ITerminalColor + Sync + Send>>(
Box::from(WinApiColor::new()),
Box::from(AnsiColor::new()),
)
.unwrap();
#[cfg(not(target_os = "windows"))]
let color = Box::from(AnsiColor::new()) as Box<ITerminalColor + Sync + Send>;
TerminalColor {
color,
stdout: Some(stdout),
}
}
pub fn set_fg(&self, color: Color) -> Result<()> {
self.color.set_fg(color, &self.stdout)
}
pub fn set_bg(&self, color: Color) -> Result<()> {
self.color.set_bg(color, &self.stdout)
}
pub fn reset(&self) -> Result<()> {
self.color.reset(&self.stdout)
}
pub fn get_available_color_count(&self) -> io::Result<u16> {
use std::env;
Ok(match env::var_os("TERM") {
Some(val) => {
if val.to_str().unwrap_or("").contains("256color") {
256
} else {
8
}
}
None => 8,
})
}
}
pub fn color<'stdout>() -> TerminalColor<'stdout> {
TerminalColor::new()
}