use std::collections::VecDeque; use std::fmt::{self, Display}; use std::rc::Rc;
/// a simple recursive type which is able to render its /// components in a tree-like format #[derive(Debug, Clone)] pubstruct Tree<D: Display> { pub root: D, pub leaves: Vec<Tree<D>>,
multiline: bool,
glyphs: Option<GlyphPalette>,
}
impl<D: Display> Display for Tree<D> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.root.fmt(f)?; // Pass along `f.alternate()`
writeln!(f)?; letmut queue = DisplauQueue::new(); let no_space = Rc::new(Vec::new()); let default_glyphs = GlyphPalette::new(); let glyphs = self.glyphs.as_ref().unwrap_or(&default_glyphs);
enqueue_leaves(&mut queue, self, glyphs, no_space); whilelet Some((last, leaf, glyphs, spaces)) = queue.pop_front() { letmut prefix = ( if last {
glyphs.last_item
} else {
glyphs.middle_item
},
glyphs.item_indent,
);
if leaf.multiline { let rest_prefix = ( if last {
glyphs.last_skip
} else {
glyphs.middle_skip
},
glyphs.skip_indent,
);
debug_assert_eq!(prefix.0.chars().count(), rest_prefix.0.chars().count());
debug_assert_eq!(prefix.1.chars().count(), rest_prefix.1.chars().count());
let root = if f.alternate() {
format!("{:#}", leaf.root)
} else {
format!("{:}", leaf.root)
}; for line in root.lines() { // print single line for s in spaces.as_slice() {
s.skip.fmt(f)?;
s.indent.fmt(f)?;
}
prefix.0.fmt(f)?;
prefix.1.fmt(f)?;
line.fmt(f)?;
writeln!(f)?;
prefix = rest_prefix;
}
} else { // print single line for s in spaces.as_slice() {
s.skip.fmt(f)?;
s.indent.fmt(f)?;
}
prefix.0.fmt(f)?;
prefix.1.fmt(f)?;
leaf.root.fmt(f)?; // Pass along `f.alternate()`
writeln!(f)?;
}
// recurse if !leaf.leaves.is_empty() { let s: &Vec<SpacePalette> = &spaces; letmut child_spaces = s.clone();
child_spaces.push(if last {
glyphs.last_space()
} else {
glyphs.middle_space()
}); let child_spaces = Rc::new(child_spaces);
enqueue_leaves(&mut queue, leaf, glyphs, child_spaces);
}
}
Ok(())
}
}
type DisplauQueue<'t, D> = VecDeque<(bool, &'t Tree<D>, &'t GlyphPalette, Rc<Vec<SpacePalette>>)>;
fn enqueue_leaves<'t, D: Display>(
queue: &mut DisplauQueue<'t, D>,
parent: &'t Tree<D>,
parent_glyphs: &'t GlyphPalette,
spaces: Rc<Vec<SpacePalette>>,
) { for (i, leaf) in parent.leaves.iter().rev().enumerate() { let last = i == 0; let glyphs = leaf.glyphs.as_ref().unwrap_or(parent_glyphs);
queue.push_front((last, leaf, glyphs, spaces.clone()));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.