use std::io::{IsTerminal, Write};
use rich::{Console, Renderable};
pub fn stderr_console() -> Console {
Console::builder()
.force_terminal(std::io::stderr().is_terminal())
.build()
}
pub fn eprint(renderable: &dyn Renderable) {
let rendered = stderr_console().render_to_string(renderable);
let mut stderr = std::io::stderr().lock();
let _ = writeln!(stderr, "{rendered}");
}
pub fn print(renderable: &dyn Renderable) {
Console::new().print(renderable);
}
#[macro_export]
macro_rules! rich_table {
([$($header:expr),* $(,)?] $(, [$($cell:expr),* $(,)?])* $(,)?) => {{
let mut table = $crate::__private::rich::Table::new();
$( table.add_column_text(
$crate::__private::rich::Text::new(::std::string::ToString::to_string(&$header)),
$crate::__private::rich::Justify::Left,
); )*
$( table.add_row_text(::std::vec![$( $crate::__private::rich::Text::new(
::std::string::ToString::to_string(&$cell),
) ),*]); )*
table
}};
}
#[macro_export]
macro_rules! rich_panel {
($markup:literal $(, $key:ident = $value:expr)* $(,)?) => {
$crate::rich_panel!(@build ::std::boxed::Box::new(
$crate::__private::rich::Text::from_markup($markup)
.unwrap_or_else(|_| $crate::__private::rich::Text::new($markup))
) $(, $key = $value)*)
};
(@build $content:expr $(, $key:ident = $value:expr)*) => {{
let panel = $crate::__private::rich::Panel::new($content);
$( let panel = panel.$key($value); )*
panel
}};
($content:expr $(, $key:ident = $value:expr)* $(,)?) => {
$crate::rich_panel!(@build ::std::boxed::Box::new($content) $(, $key = $value)*)
};
}
#[macro_export]
macro_rules! rich_tree {
($label:expr $(=> [$($children:tt)*])?) => {{
#[allow(unused_mut)]
let mut tree = $crate::__private::rich::Tree::new($crate::__private::rich::Text::new($label));
$( $crate::rich_tree!(@children tree; $($children)*); )?
tree
}};
(@children $parent:ident; ) => {};
(@children $parent:ident; $label:expr => [$($children:tt)*] $(, $($rest:tt)*)?) => {{
let node = $parent.add($crate::__private::rich::Text::new($label));
$crate::rich_tree!(@children node; $($children)*);
$( $crate::rich_tree!(@children $parent; $($rest)*); )?
}};
(@children $parent:ident; $label:expr $(, $($rest:tt)*)?) => {{
$parent.add($crate::__private::rich::Text::new($label));
$( $crate::rich_tree!(@children $parent; $($rest)*); )?
}};
}
#[macro_export]
macro_rules! rich_progress {
($iter:expr, $description:expr $(,)?) => {
$crate::__private::rich::track($iter, $description)
};
($iter:expr $(,)?) => {
$crate::__private::rich::track($iter, "Working...")
};
}
#[macro_export]
macro_rules! rich_dbg {
() => {
$crate::macros::eprint(&$crate::__private::rich::Text::styled(
::std::format!("[{}:{}:{}]", ::std::file!(), ::std::line!(), ::std::column!()),
"dim",
))
};
($value:expr $(,)?) => {
match $value {
value => {
$crate::macros::eprint(&$crate::macros::dbg_line(
::std::file!(),
::std::line!(),
::std::column!(),
::std::stringify!($value),
&value,
));
value
}
}
};
($($value:expr),+ $(,)?) => {
($($crate::rich_dbg!($value)),+,)
};
}
pub fn dbg_line(
file: &str,
line: u32,
column: u32,
expression: &str,
value: &dyn std::fmt::Debug,
) -> rich::Text {
use rich::Highlighter;
let mut text = rich::Text::styled(format!("[{file}:{line}:{column}] "), "dim");
text.append(expression, Some("bold".into()));
text.append(" = ", None);
let mut rendered = rich::Text::new(format!("{value:#?}"));
rich::ReprHighlighter::new().highlight(&mut rendered);
text.append_text(&rendered)
}
#[cfg(feature = "macros")]
#[macro_export]
macro_rules! rich_println {
($($arg:tt)*) => {
$crate::macros::print(&$crate::richf!($($arg)*))
};
}
#[cfg(feature = "macros")]
#[macro_export]
macro_rules! rich_eprintln {
($($arg:tt)*) => {
$crate::macros::eprint(&$crate::richf!($($arg)*))
};
}
#[cfg(feature = "macros")]
#[macro_export]
macro_rules! rich_trace {
($($arg:tt)*) => {
$crate::macros::eprint(&$crate::__private::rich::Text::styled(
::std::format!("{}:{} ", ::std::file!(), ::std::line!()),
"dim",
).append_text(&$crate::richf!($($arg)*)))
};
}