use std::io;
#[macro_export]
macro_rules! term_write {
( $term:expr , $first:tt $($rest:tt)* ) => {
match $term.borrow_term_write_guard() {
mut term => {
let init = $crate::macros::Chain::init();
term_write!(@_INTERNAL main: term ; init ; $first $($rest)*)
}
}
};
( @_INTERNAL main: $term:expr ; $result:expr ; ) => {
$result
};
( @_INTERNAL main: $term:expr ; $result:expr ; [ $($tt:tt)* ] $($rest:tt)* ) => {
term_write!(
@_INTERNAL main: $term;
term_write!(@_INTERNAL style: $term; $result; $($tt)*);
$($rest)*
)
};
( @_INTERNAL main: $term:expr ; $result:expr ; ( $($tt:tt)* ) $($rest:tt)* ) => {
term_write!(
@_INTERNAL main: $term;
term_write!(@_INTERNAL format: $term; $result; $($tt)*);
$($rest)*
)
};
( @_INTERNAL main: $term:expr ; $result:expr ; $tt:tt $($rest:tt)* ) => {
term_write!(
@_INTERNAL main: $term;
term_write!(@_INTERNAL literal: $term; $result; $tt);
$($rest)*
)
};
( @_INTERNAL style: $term:expr ; $result:expr ; black ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Black))
};
( @_INTERNAL style: $term:expr ; $result:expr ; blue ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Blue))
};
( @_INTERNAL style: $term:expr ; $result:expr ; cyan ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Cyan))
};
( @_INTERNAL style: $term:expr ; $result:expr ; green ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Green))
};
( @_INTERNAL style: $term:expr ; $result:expr ; magenta ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Magenta))
};
( @_INTERNAL style: $term:expr ; $result:expr ; red ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Red))
};
( @_INTERNAL style: $term:expr ; $result:expr ; white ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::White))
};
( @_INTERNAL style: $term:expr ; $result:expr ; yellow ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($crate::Color::Yellow))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # black ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Black))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # blue ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Blue))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # cyan ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Cyan))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # green ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Green))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # magenta ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Magenta))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # red ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Red))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # white ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::White))
};
( @_INTERNAL style: $term:expr ; $result:expr ; # yellow ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($crate::Color::Yellow))
};
( @_INTERNAL style: $term:expr ; $result:expr ; bold ) => {
$crate::macros::Chain::chain(
$result, || $term.add_style($crate::Style::BOLD))
};
( @_INTERNAL style: $term:expr ; $result:expr ; italic ) => {
$crate::macros::Chain::chain(
$result, || $term.add_style($crate::Style::ITALIC))
};
( @_INTERNAL style: $term:expr ; $result:expr ; reverse ) => {
$crate::macros::Chain::chain(
$result, || $term.add_style($crate::Style::REVERSE))
};
( @_INTERNAL style: $term:expr ; $result:expr ; underline ) => {
$crate::macros::Chain::chain(
$result, || $term.add_style($crate::Style::UNDERLINE))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! bold ) => {
$crate::macros::Chain::chain(
$result, || $term.remove_style($crate::Style::BOLD))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! italic ) => {
$crate::macros::Chain::chain(
$result, || $term.remove_style($crate::Style::ITALIC))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! reverse ) => {
$crate::macros::Chain::chain(
$result, || $term.remove_style($crate::Style::REVERSE))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! underline ) => {
$crate::macros::Chain::chain(
$result, || $term.remove_style($crate::Style::UNDERLINE))
};
( @_INTERNAL style: $term:expr ; $result:expr ; reset ) => {
$crate::macros::Chain::chain(
$result, || $term.clear_attributes())
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! fg ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg(None))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! bg ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg(None))
};
( @_INTERNAL style: $term:expr ; $result:expr ; ! style ) => {
$crate::macros::Chain::chain(
$result, || $term.set_style(None))
};
( @_INTERNAL style: $term:expr ; $result:expr ; fg = $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.set_fg($e))
};
( @_INTERNAL style: $term:expr ; $result:expr ; bg = $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.set_bg($e))
};
( @_INTERNAL style: $term:expr ; $result:expr ; style = $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.set_style($e))
};
( @_INTERNAL style: $term:expr ; $result:expr ; style += $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.add_style($e))
};
( @_INTERNAL style: $term:expr ; $result:expr ; style -= $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.remove_style($e))
};
( @_INTERNAL style: $term:expr ; $result:expr ; theme = $e:expr ) => {
$crate::macros::Chain::chain(
$result, || $term.set_theme($e))
};
( @_INTERNAL format: $term:expr ; $result:expr ; : $e:expr ) => {
$crate::macros::Chain::chain(
$result, || write!($term, "{}", $e))
};
( @_INTERNAL format: $term:expr ; $result:expr ; ? $e:expr ) => {
$crate::macros::Chain::chain(
$result, || write!($term, "{:?}", $e))
};
( @_INTERNAL format: $term:expr ; $result:expr ; $($tt:tt)* ) => {
$crate::macros::Chain::chain(
$result, || write!($term, $($tt)*))
};
( @_INTERNAL literal: $term:expr ; $result:expr ; $lit:tt ) => {
$crate::macros::Chain::chain(
$result, || $term.write_str(concat!($lit)))
};
}
#[macro_export]
macro_rules! term_writeln {
( $term:expr ) => {
term_write!($term, "\n")
};
( $term:expr , $($tt:tt)* ) => {
term_write!($term, $($tt)* "\n")
};
}
#[doc(hidden)]
pub trait Chain: Sized {
fn chain<F: FnOnce() -> Self>(self, f: F) -> Self;
fn init() -> Self;
}
impl Chain for () {
fn chain<F: FnOnce() -> Self>(self, f: F) -> Self {
f()
}
fn init() -> Self { }
}
impl Chain for io::Result<()> {
fn chain<F: FnOnce() -> Self>(self, f: F) -> Self {
self.and_then(|_| f())
}
fn init() -> Self { Ok(()) }
}