1use std::io::{IsTerminal, Write};
12
13use rich::{Console, Renderable};
14
15pub fn stderr_console() -> Console {
17 Console::builder()
18 .force_terminal(std::io::stderr().is_terminal())
19 .build()
20}
21
22pub fn eprint(renderable: &dyn Renderable) {
24 let rendered = stderr_console().render_to_string(renderable);
25 let mut stderr = std::io::stderr().lock();
26 let _ = writeln!(stderr, "{rendered}");
27}
28
29pub fn print(renderable: &dyn Renderable) {
31 Console::new().print(renderable);
32}
33
34#[macro_export]
42macro_rules! rich_table {
43 ([$($header:expr),* $(,)?] $(, [$($cell:expr),* $(,)?])* $(,)?) => {{
44 let mut table = $crate::__private::rich::Table::new();
45 $( table.add_column_text(
46 $crate::__private::rich::Text::new(::std::string::ToString::to_string(&$header)),
47 $crate::__private::rich::Justify::Left,
48 ); )*
49 $( table.add_row_text(::std::vec![$( $crate::__private::rich::Text::new(
50 ::std::string::ToString::to_string(&$cell),
51 ) ),*]); )*
52 table
53 }};
54}
55
56#[macro_export]
64macro_rules! rich_panel {
65 ($markup:literal $(, $key:ident = $value:expr)* $(,)?) => {
66 $crate::rich_panel!(@build ::std::boxed::Box::new(
67 $crate::__private::rich::Text::from_markup($markup)
68 .unwrap_or_else(|_| $crate::__private::rich::Text::new($markup))
69 ) $(, $key = $value)*)
70 };
71 (@build $content:expr $(, $key:ident = $value:expr)*) => {{
72 let panel = $crate::__private::rich::Panel::new($content);
73 $( let panel = panel.$key($value); )*
74 panel
75 }};
76 ($content:expr $(, $key:ident = $value:expr)* $(,)?) => {
77 $crate::rich_panel!(@build ::std::boxed::Box::new($content) $(, $key = $value)*)
78 };
79}
80
81#[macro_export]
89macro_rules! rich_tree {
90 ($label:expr $(=> [$($children:tt)*])?) => {{
91 #[allow(unused_mut)]
92 let mut tree = $crate::__private::rich::Tree::new($crate::__private::rich::Text::new($label));
93 $( $crate::rich_tree!(@children tree; $($children)*); )?
94 tree
95 }};
96 (@children $parent:ident; ) => {};
97 (@children $parent:ident; $label:expr => [$($children:tt)*] $(, $($rest:tt)*)?) => {{
98 let node = $parent.add($crate::__private::rich::Text::new($label));
99 $crate::rich_tree!(@children node; $($children)*);
100 $( $crate::rich_tree!(@children $parent; $($rest)*); )?
101 }};
102 (@children $parent:ident; $label:expr $(, $($rest:tt)*)?) => {{
103 $parent.add($crate::__private::rich::Text::new($label));
104 $( $crate::rich_tree!(@children $parent; $($rest)*); )?
105 }};
106}
107
108#[macro_export]
114macro_rules! rich_progress {
115 ($iter:expr, $description:expr $(,)?) => {
116 $crate::__private::rich::track($iter, $description)
117 };
118 ($iter:expr $(,)?) => {
119 $crate::__private::rich::track($iter, "Working...")
120 };
121}
122
123#[macro_export]
131macro_rules! rich_dbg {
132 () => {
133 $crate::macros::eprint(&$crate::__private::rich::Text::styled(
134 ::std::format!("[{}:{}:{}]", ::std::file!(), ::std::line!(), ::std::column!()),
135 "dim",
136 ))
137 };
138 ($value:expr $(,)?) => {
139 match $value {
140 value => {
141 $crate::macros::eprint(&$crate::macros::dbg_line(
142 ::std::file!(),
143 ::std::line!(),
144 ::std::column!(),
145 ::std::stringify!($value),
146 &value,
147 ));
148 value
149 }
150 }
151 };
152 ($($value:expr),+ $(,)?) => {
153 ($($crate::rich_dbg!($value)),+,)
154 };
155}
156
157pub fn dbg_line(
160 file: &str,
161 line: u32,
162 column: u32,
163 expression: &str,
164 value: &dyn std::fmt::Debug,
165) -> rich::Text {
166 use rich::Highlighter;
167 let mut text = rich::Text::styled(format!("[{file}:{line}:{column}] "), "dim");
168 text.append(expression, Some("bold".into()));
169 text.append(" = ", None);
170 let mut rendered = rich::Text::new(format!("{value:#?}"));
171 rich::ReprHighlighter::new().highlight(&mut rendered);
172 text.append_text(&rendered)
173}
174
175#[cfg(feature = "macros")]
177#[macro_export]
178macro_rules! rich_println {
179 ($($arg:tt)*) => {
180 $crate::macros::print(&$crate::richf!($($arg)*))
181 };
182}
183
184#[cfg(feature = "macros")]
186#[macro_export]
187macro_rules! rich_eprintln {
188 ($($arg:tt)*) => {
189 $crate::macros::eprint(&$crate::richf!($($arg)*))
190 };
191}
192
193#[cfg(feature = "macros")]
196#[macro_export]
197macro_rules! rich_trace {
198 ($($arg:tt)*) => {
199 $crate::macros::eprint(&$crate::__private::rich::Text::styled(
200 ::std::format!("{}:{} ", ::std::file!(), ::std::line!()),
201 "dim",
202 ).append_text(&$crate::richf!($($arg)*)))
203 };
204}