use std::{env, fmt::Display};
#[cfg(windows)]
use crate::Result;
use crate::{impl_display, Ansi, Command};
use std::fmt;
pub use self::{
attributes::Attributes,
content_style::ContentStyle,
styled_content::StyledContent,
traits::{Colorize, Styler},
types::{Attribute, Color, Colored, Colors},
};
#[macro_use]
mod macros;
mod ansi;
mod attributes;
mod content_style;
mod styled_content;
mod sys;
mod traits;
mod types;
pub fn style<'a, D: 'a>(val: D) -> StyledContent<D>
where
D: Display + Clone,
{
ContentStyle::new().apply(val)
}
impl_colorize!(String);
impl_colorize!(char);
#[allow(unused_parens)]
impl<'a> Colorize<&'a str> for &'a str {
impl_colorize_callback!(def_color_base!((&'a str)));
}
impl_styler!(String);
impl_styler!(char);
#[allow(unused_parens)]
impl<'a> Styler<&'a str> for &'a str {
impl_styler_callback!(def_attr_base!((&'a str)));
}
pub fn available_color_count() -> u16 {
env::var("TERM")
.map(|x| if x.contains("256color") { 256 } else { 8 })
.unwrap_or(8)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SetForegroundColor(pub Color);
impl fmt::Display for Ansi<SetForegroundColor> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ansi::set_fg_csi_sequence(f, (self.0).0)
}
}
impl Command for SetForegroundColor {
type AnsiType = Ansi<Self>;
#[inline]
fn ansi_code(&self) -> Self::AnsiType {
Ansi(*self)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::windows::set_foreground_color(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SetBackgroundColor(pub Color);
impl fmt::Display for Ansi<SetBackgroundColor> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ansi::set_bg_csi_sequence(f, (self.0).0)
}
}
impl Command for SetBackgroundColor {
type AnsiType = Ansi<Self>;
#[inline]
fn ansi_code(&self) -> Self::AnsiType {
Ansi(*self)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::windows::set_background_color(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SetColors(pub Colors);
impl fmt::Display for Ansi<SetColors> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(color) = (self.0).0.foreground {
ansi::set_fg_csi_sequence(f, color)?;
}
if let Some(color) = (self.0).0.background {
ansi::set_bg_csi_sequence(f, color)?;
}
Ok(())
}
}
impl Command for SetColors {
type AnsiType = Ansi<Self>;
#[inline]
fn ansi_code(&self) -> Self::AnsiType {
Ansi(*self)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
if let Some(color) = self.0.foreground {
sys::windows::set_foreground_color(color)?;
}
if let Some(color) = self.0.background {
sys::windows::set_background_color(color)?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SetAttribute(pub Attribute);
impl fmt::Display for Ansi<SetAttribute> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ansi::set_attr_csi_sequence(f, (self.0).0)
}
}
impl Command for SetAttribute {
type AnsiType = Ansi<Self>;
#[inline]
fn ansi_code(&self) -> Self::AnsiType {
Ansi(*self)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SetAttributes(pub Attributes);
impl fmt::Display for Ansi<SetAttributes> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ansi::set_attrs_csi_sequence(f, (self.0).0)
}
}
impl Command for SetAttributes {
type AnsiType = Ansi<Self>;
fn ansi_code(&self) -> Self::AnsiType {
Ansi(*self)
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct PrintStyledContent<D: Display + Clone>(pub StyledContent<D>);
impl<D> Command for PrintStyledContent<D>
where
D: Display + Clone,
{
type AnsiType = StyledContent<D>;
fn ansi_code(&self) -> Self::AnsiType {
self.0.clone()
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ResetColor;
impl Command for ResetColor {
type AnsiType = &'static str;
fn ansi_code(&self) -> Self::AnsiType {
ansi::RESET_CSI_SEQUENCE
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
sys::windows::reset()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Print<T: Display + Clone>(pub T);
impl<T: Display + Clone> Command for Print<T> {
type AnsiType = T;
fn ansi_code(&self) -> Self::AnsiType {
self.0.clone()
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<()> {
print!("{}", self.0);
Ok(())
}
}
impl<T: Display + Clone> Display for Print<T> {
fn fmt(
&self,
f: &mut ::std::fmt::Formatter<'_>,
) -> ::std::result::Result<(), ::std::fmt::Error> {
write!(f, "{}", self.ansi_code())
}
}
impl_display!(for SetForegroundColor);
impl_display!(for SetBackgroundColor);
impl_display!(for SetColors);
impl_display!(for SetAttribute);
impl_display!(for PrintStyledContent<String>);
impl_display!(for PrintStyledContent<&'static str>);
impl_display!(for ResetColor);