use super::{stderr, stdout};
use crate::FrameworkError;
use std::io::Write;
use termcolor::{Color, ColorSpec, StandardStream, WriteColor};
#[macro_export]
macro_rules! status_ok {
($status:expr, $msg:expr) => {
$crate::terminal::status::Status::new()
.justified()
.bold()
.color($crate::terminal::Color::Green)
.status($status)
.print_stderr($msg)
.unwrap();
};
($status:expr, $fmt:expr, $($arg:tt)+) => {
$crate::status_ok!($status, format!($fmt, $($arg)+));
};
}
#[macro_export]
macro_rules! status_info {
($status:expr, $msg:expr) => {
$crate::terminal::status::Status::new()
.justified()
.bold()
.color($crate::terminal::Color::Cyan)
.status($status)
.print_stderr($msg)
.unwrap();
};
($status:expr, $fmt:expr, $($arg:tt)+) => {
$crate::status_info!($status, format!($fmt, $($arg)+));
};
}
#[macro_export]
macro_rules! status_warn {
($msg:expr) => {
$crate::terminal::status::Status::new()
.bold()
.color($crate::terminal::Color::Yellow)
.status("warning:")
.print_stderr($msg)
.unwrap();
};
($fmt:expr, $($arg:tt)+) => {
$crate::status_warn!(format!($fmt, $($arg)+));
};
}
#[macro_export]
macro_rules! status_err {
($msg:expr) => {
$crate::terminal::status::Status::new()
.bold()
.color($crate::terminal::Color::Red)
.status("error:")
.print_stderr($msg)
.unwrap();
};
($fmt:expr, $($arg:tt)+) => {
$crate::status_err!(format!($fmt, $($arg)+));
};
}
#[macro_export]
macro_rules! status_attr_ok {
($attr:expr, $msg:expr) => {
let attr_delimited = if $attr.len() >= 7 {
format!("{}:", $attr)
} else {
format!("{}:\t", $attr)
};
$crate::terminal::status::Status::new()
.bold()
.color($crate::terminal::Color::Green)
.status(attr_delimited)
.print_stdout($msg)
.unwrap();
};
($attr: expr, $fmt:expr, $($arg:tt)+) => {
$crate::status_attr_ok!($attr, format!($fmt, $($arg)+));
}
}
#[macro_export]
macro_rules! status_attr_err {
($attr:expr, $msg:expr) => {
let attr_delimited = if $attr.len() >= 7 {
format!("{}:", $attr)
} else {
format!("{}:\t", $attr)
};
$crate::terminal::status::Status::new()
.bold()
.color($crate::terminal::Color::Red)
.status(attr_delimited)
.print_stdout($msg)
.unwrap();
};
($attr: expr, $fmt:expr, $($arg:tt)+) => {
$crate::status_attr_err!($attr, format!($fmt, $($arg)+));
}
}
#[derive(Clone, Debug, Default)]
pub struct Status {
justified: bool,
bold: bool,
color: Option<Color>,
status: Option<String>,
}
impl Status {
pub fn new() -> Self {
Self::default()
}
pub fn justified(mut self) -> Self {
self.justified = true;
self
}
pub fn bold(mut self) -> Self {
self.bold = true;
self
}
pub fn color(mut self, c: Color) -> Self {
self.color = Some(c);
self
}
pub fn status<S>(mut self, msg: S) -> Self
where
S: ToString,
{
self.status = Some(msg.to_string());
self
}
pub fn print_stdout<S>(self, msg: S) -> Result<(), FrameworkError>
where
S: AsRef<str>,
{
self.print(stdout(), msg)
}
pub fn print_stderr<S>(self, msg: S) -> Result<(), FrameworkError>
where
S: AsRef<str>,
{
self.print(stderr(), msg)
}
fn print<S>(self, stream: &StandardStream, msg: S) -> Result<(), FrameworkError>
where
S: AsRef<str>,
{
let mut s = stream.lock();
s.reset()?;
s.set_color(ColorSpec::new().set_fg(self.color).set_bold(self.bold))?;
if let Some(status) = self.status {
if self.justified {
write!(s, "{:>12}", status)?;
} else {
write!(s, "{}", status)?;
}
}
s.reset()?;
let msg = msg.as_ref();
if !msg.is_empty() {
writeln!(s, " {}", msg)?;
}
s.flush()?;
Ok(())
}
}