use std::fmt::{self, Formatter, Alignment, Debug};
#[doc(hidden)]
pub fn pad(t: &impl Debug, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
if f.alternate() {
let s = if let Some(width) = f.width() {
let s = if let Some(precision) = f.precision() {
match f.align().unwrap_or(Alignment::Left) {
Alignment::Left => {
format!("{:\x7F<#width$.precision$?}", t, width = width, precision = precision)
}
Alignment::Right => {
format!("{:\x7F>#width$.precision$?}", t, width = width, precision = precision)
}
Alignment::Center => {
format!("{:\x7F^#width$.precision$?}", t, width = width, precision = precision)
}
}
} else {
match f.align().unwrap_or(Alignment::Left) {
Alignment::Left => {
format!("{:\x7F<#width$?}", t, width = width)
}
Alignment::Right => {
format!("{:\x7F>#width$?}", t, width = width)
}
Alignment::Center => {
format!("{:\x7F^#width$?}", t, width = width)
}
}
};
s.replace("\x7F", &f.fill().to_string())
} else {
if let Some(precision) = f.precision() {
format!("{:#.precision$?}", t, precision = precision)
} else {
format!("{:#?}", t)
}
};
f.write_str(&s.replace("\n", "\n "))
} else {
Debug::fmt(t, f)
}
}
#[macro_export]
macro_rules! impl_debug_for_struct {
($struct_name:ident, $formatter:expr $(, $self:expr)? $(,)*) => {
return $formatter.write_str(stringify!($struct_name));
};
($struct_name:ident, $formatter:expr, $self:expr, $(.$first_field:ident)? $((.$first_field_2:ident, $($first_field_2_fmt:tt)+))? $(, $(.$field:ident)? $((.$field_2:ident, $($field_2_fmt:tt)+))? $((/$field_3:ident, $($field_3_fmt:tt)+))?)* $(,)*) => {
{
use std::fmt::Write;
$formatter.write_str(stringify!($struct_name))?;
let separator = if $formatter.alternate() {
$formatter.write_str(" {\n ")?;
"\n "
} else {
$formatter.write_str(" { ")?;
", "
};
$(
$formatter.write_str(stringify!($first_field))?;
$formatter.write_str(": ")?;
$crate::pad(&$self.$first_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(stringify!($first_field_2))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($first_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($first_field_2_fmt)*))?;
}
)?
$(
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($field))?;
$formatter.write_str(": ")?;
$crate::pad(&$self.$field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($field_2))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($field_2_fmt)*))?;
}
)?
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($field_3))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($field_3_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($field_3_fmt)*))?;
}
)?
)*
if $formatter.alternate() {
return $formatter.write_str("\n}");
} else {
return $formatter.write_str(" }");
}
}
};
}
#[macro_export]
macro_rules! impl_debug_for_tuple_struct {
($struct_name:ident, $formatter:expr $(, $self:expr)? $(,)*) => {
return $formatter.write_str(stringify!($struct_name));
};
($struct_name:ident, $formatter:expr, $self:expr, $(.$first_field:tt)? $((.$first_field_2:tt, $($first_field_2_fmt:tt)+))? $(, $(.$field:tt)? $((.$field_2:tt, $($field_2_fmt:tt)+))?)* $(,)*) => {
{
use std::fmt::Write;
$formatter.write_str(stringify!($struct_name))?;
let separator = if $formatter.alternate() {
$formatter.write_str("(\n ")?;
"\n "
} else {
$formatter.write_str("(")?;
", "
};
$(
$crate::pad(&$self.$first_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
if $formatter.alternate() {
$formatter.write_str(&format!($($first_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($first_field_2_fmt)*))?;
}
)?
$(
$(
$formatter.write_str(separator)?;
$crate::pad(&$self.$field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(separator)?;
if $formatter.alternate() {
$formatter.write_str(&format!($($field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($field_2_fmt)*))?;
}
)?
)*
if $formatter.alternate() {
return $formatter.write_str("\n)");
} else {
return $formatter.write_str(")");
}
}
}
}
#[macro_export]
macro_rules! impl_debug_for_enum {
($enum_name:ident::{$( $($variant_unit:ident)? $(($variant_tuple:ident ($($tuple:tt)*) $(:($(.$t_first_field:tt)? $((.$t_first_field_2:tt, $($t_first_field_2_fmt:tt)+))? $(, $(.$t_field:tt)? $((.$t_field_2:tt, $($t_field_2_fmt:tt)+))?)* $(,)*))? ) )? $({$variant_struct:ident {$($struct:tt)*} $(:($(.$s_first_field:tt)? $((.$s_first_field_2:tt, $($s_first_field_2_fmt:tt)+))? $(, $(.$s_field:tt)? $((.$s_field_2:tt, $($s_field_2_fmt:tt)+))? $((/$s_field_3:tt, $($s_field_3_fmt:tt)+))?)* $(,)*))? })? ),+ $(,)*}, $formatter:expr, $self:expr $(,)*) => {
{
use std::fmt::Write;
match $self {
$(
$(
Self::$variant_unit => {
return $formatter.write_str(stringify!($variant_unit));
}
)?
$(
Self::$variant_tuple ($($tuple)*)=> {
let mut result = $formatter.write_str(stringify!($variant_tuple));
$(
let separator = if $formatter.alternate() {
$formatter.write_str("(\n ")?;
"\n "
} else {
$formatter.write_str("(")?;
", "
};
$(
$crate::pad(&$t_first_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
if $formatter.alternate() {
$formatter.write_str(&format!($($t_first_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($t_first_field_2_fmt)*))?;
}
)?
$(
$(
$formatter.write_str(separator)?;
$crate::pad(&$t_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(separator)?;
if $formatter.alternate() {
$formatter.write_str(&format!($($t_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($t_field_2_fmt)*))?;
}
)?
)*
result = if $formatter.alternate() {
$formatter.write_str("\n)")
} else {
$formatter.write_str(")")
};
)?
return result;
}
)?
$(
Self::$variant_struct {$($struct)*}=> {
let mut result = $formatter.write_str(stringify!($variant_struct));
$(
let separator = if $formatter.alternate() {
$formatter.write_str(" {\n ")?;
"\n "
} else {
$formatter.write_str(" { ")?;
", "
};
$(
$formatter.write_str(stringify!($s_first_field))?;
$formatter.write_str(": ")?;
$crate::pad(&$s_first_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(stringify!($s_first_field_2))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($s_first_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($s_first_field_2_fmt)*))?;
}
)?
$(
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($s_field))?;
$formatter.write_str(": ")?;
$crate::pad(&$s_field, $formatter)?;
if $formatter.alternate() {
$formatter.write_char(',')?;
}
)?
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($s_field_2))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($s_field_2_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($s_field_2_fmt)*))?;
}
)?
$(
$formatter.write_str(separator)?;
$formatter.write_str(stringify!($s_field_3))?;
$formatter.write_str(": ")?;
if $formatter.alternate() {
$formatter.write_str(&format!($($s_field_3_fmt)*).replace("\n", "\n "))?;
$formatter.write_char(',')?;
} else {
$formatter.write_fmt(format_args!($($s_field_3_fmt)*))?;
}
)?
)*
result = if $formatter.alternate() {
$formatter.write_str("\n}")
} else {
$formatter.write_str(" }")
};
)?
return result;
}
)?
)+
}
}
};
}