88 lines
2.0 KiB
Rust
88 lines
2.0 KiB
Rust
#[derive(Debug, Clone, Copy)]
|
|
pub struct ReportFmt {
|
|
indentation: usize,
|
|
is_first: bool,
|
|
indent_first: bool,
|
|
}
|
|
|
|
impl ReportFmt {
|
|
#[inline]
|
|
pub fn indent(mut self) -> Self {
|
|
self.indentation += 1;
|
|
self
|
|
}
|
|
|
|
#[inline]
|
|
pub fn next(mut self) -> Self {
|
|
self.is_first = false;
|
|
self
|
|
}
|
|
|
|
#[inline]
|
|
pub fn indent_first(mut self, indent_first: bool) -> Self {
|
|
self.indent_first = indent_first;
|
|
self
|
|
}
|
|
|
|
/// Returns the amount of indentation.
|
|
#[inline]
|
|
pub fn indentation(&self) -> usize {
|
|
self.indentation
|
|
}
|
|
|
|
#[inline]
|
|
pub fn should_indent(&self) -> bool {
|
|
self.indent_first || !self.is_first
|
|
}
|
|
}
|
|
|
|
impl Default for ReportFmt {
|
|
#[inline]
|
|
fn default() -> Self {
|
|
Self {
|
|
indentation: 0,
|
|
indent_first: true,
|
|
is_first: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! report_write {
|
|
($f:expr, $opts:expr, $msg:literal$(, $($tt:tt)+)?) => {
|
|
<std::fmt::Arguments<'_> as $crate::Report>::fmt(&format_args!($msg$(, $($tt)+)?), $f, $opts)
|
|
};
|
|
}
|
|
pub(crate) use report_write;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub(crate) struct Indentation(pub usize);
|
|
|
|
impl std::fmt::Display for Indentation {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
use std::fmt::Write;
|
|
for _ in 0..self.0 {
|
|
f.write_char(' ')?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// A more flexible formatting type that is a cross between [`std::fmt::Debug`] and
|
|
/// [`std::fmt::Display`].
|
|
pub trait Report {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>, opts: &ReportFmt) -> std::fmt::Result;
|
|
}
|
|
|
|
impl<T> Report for T
|
|
where
|
|
T: std::fmt::Display,
|
|
{
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>, opts: &ReportFmt) -> std::fmt::Result {
|
|
if opts.should_indent() {
|
|
write!(f, "{}", Indentation(opts.indentation()))?;
|
|
}
|
|
<T as std::fmt::Display>::fmt(self, f)?;
|
|
Ok(())
|
|
}
|
|
}
|