tree-mumu 0.1.0-rc.2

Creates Linux `tree`-style renderings of MuMu values
Documentation
// src/share/render.rs
//
// Render a Node tree into Linux `tree`-style text lines.

use super::glyphs::{GlyphSet, head, indent_prefix};
use super::walk::Node;

/// Render the full set of lines for a tree, using the provided glyph set.
/// The first line prints the root's name, then its children are rendered with
/// connectors.
pub fn render_lines(root: &Node, glyphs: &GlyphSet) -> Vec<String> {
    let mut lines = Vec::new();
    let root_name = if root.name.is_empty() { "<root>" } else { &root.name };
    lines.push(root_name.to_string());

    if !root.children.is_empty() {
        emit_children(&root.children, &mut Vec::new(), glyphs, &mut lines);
    } else if let Some(text) = &root.leaf {
        if !text.is_empty() {
            lines.push(format!("{}{}", head(true, glyphs), text));
        }
    }

    lines
}

fn emit_children(children: &[Node], ancestors_more: &mut Vec<bool>, glyphs: &GlyphSet, out: &mut Vec<String>) {
    let last_idx = children.len().saturating_sub(1);
    for (idx, child) in children.iter().enumerate() {
        let is_last = idx == last_idx;
        let ind = indent_prefix(ancestors_more, glyphs);
        let h = head(is_last, glyphs);

        match (&child.leaf, child.children.is_empty()) {
            (Some(text), true) => {
                if child.name.is_empty() {
                    out.push(format!("{}{}{}", ind, h, text));
                } else if text.is_empty() {
                    out.push(format!("{}{}{}", ind, h, child.name));
                } else {
                    out.push(format!("{}{}{}: {}", ind, h, child.name, text));
                }
            }
            _ => {
                let name = if child.name.is_empty() { "<node>" } else { &child.name };
                out.push(format!("{}{}{}", ind, h, name));

                ancestors_more.push(!is_last);
                emit_children(&child.children, ancestors_more, glyphs, out);
                ancestors_more.pop();
            }
        }
    }
}