Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Last active November 5, 2021 16:50
Show Gist options
  • Save AnthonyMikh/366edfdd31409a754b4665e555b9b6a3 to your computer and use it in GitHub Desktop.
Save AnthonyMikh/366edfdd31409a754b4665e555b9b6a3 to your computer and use it in GitHub Desktop.
Pretty Debug implementation for heterogrenous list
struct HNil;
struct HCons<H, T> {
head: H,
tail: T,
}
#[cfg(feature = "")]
mod via_debug_vec {
use super::{HCons, HNil};
use std::fmt::{self, Debug};
pub trait AppendFmt {
fn append_fmt_items<'a>(&'a self, items: &mut Vec<&'a dyn Debug>);
}
impl AppendFmt for HNil {
fn append_fmt_items<'a>(&'a self, _: &mut Vec<&'a dyn Debug>) {}
}
impl<H, T> AppendFmt for HCons<H, T>
where
H: Debug,
T: AppendFmt,
{
fn append_fmt_items<'a>(&'a self, items: &mut Vec<&'a dyn Debug>) {
items.push(&self.head);
self.tail.append_fmt_items(items);
}
}
impl Debug for HNil {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let list: &[&dyn Debug] = &[];
list.fmt(f)
}
}
impl<H, T> Debug for HCons<H, T>
where
Self: AppendFmt,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut items = Vec::new();
self.append_fmt_items(&mut items);
items.fmt(f)
}
}
}
// #[cfg(feature = "")]
mod via_finish_fmt {
use super::{HCons, HNil};
use std::fmt::{self, Debug, DebugList};
pub trait HlistFmt {
fn finish_fmt(&self, list: &mut DebugList<'_, '_>) -> fmt::Result;
}
impl HlistFmt for HNil {
fn finish_fmt(&self, list: &mut DebugList<'_, '_>) -> fmt::Result {
list.finish()
}
}
impl<H, T> HlistFmt for HCons<H, T>
where
H: Debug,
T: HlistFmt,
{
fn finish_fmt(&self, list: &mut DebugList<'_, '_>) -> fmt::Result {
list.entry(&self.head);
self.tail.finish_fmt(list)
}
}
impl Debug for HNil {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.finish_fmt(&mut f.debug_list())
}
}
impl<H, T> Debug for HCons<H, T>
where
Self: HlistFmt,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.finish_fmt(&mut f.debug_list())
}
}
}
macro_rules! hlist {
($head:expr $(, $e:expr)* $(,)?) => {
HCons {
head: $head,
tail: hlist![$($e,)*],
}
};
() => { HNil };
}
fn main() {
let list = hlist![42, 'b', "sup", ((), (3.4, Vec::<i32>::new()))];
println!("{:?}", list);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment