use core::fmt;
use core::marker::PhantomData;
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PrettyIndent {
prefix: &'static str,
level: usize,
}
impl PrettyIndent {
pub fn new(prefix: &'static str) -> PrettyIndent {
PrettyIndent { prefix, level: 0 }
}
pub fn increase(&mut self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f)?;
self.level += 1;
Ok(())
}
}
impl fmt::Display for PrettyIndent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.level == 0 {
write!(f, "{}", self.prefix)
} else {
write!(f, "{0:1$}{0:2$}\\ ", "", self.prefix.len(), self.level - 1)
}
}
}
pub trait PrettyPrint {
fn pretty_print(
buffer: &dyn AsRef<[u8]>,
fmt: &mut fmt::Formatter,
indent: &mut PrettyIndent,
) -> fmt::Result;
}
pub struct PrettyPrinter<'a, T: PrettyPrint> {
prefix: &'static str,
buffer: &'a dyn AsRef<[u8]>,
phantom: PhantomData<T>,
}
impl<'a, T: PrettyPrint> PrettyPrinter<'a, T> {
pub fn new(prefix: &'static str, buffer: &'a dyn AsRef<[u8]>) -> PrettyPrinter<'a, T> {
PrettyPrinter {
prefix: prefix,
buffer: buffer,
phantom: PhantomData,
}
}
}
impl<'a, T: PrettyPrint + AsRef<[u8]>> PrettyPrinter<'a, T> {
pub fn print(printable: &'a T) -> PrettyPrinter<'a, T> {
PrettyPrinter {
prefix: "",
buffer: printable,
phantom: PhantomData,
}
}
}
impl<'a, T: PrettyPrint> fmt::Display for PrettyPrinter<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
T::pretty_print(&self.buffer, f, &mut PrettyIndent::new(self.prefix))
}
}