about summary refs log blame commit diff stats
path: root/pkgs/by-name/lf/lf-make-map/src/mapping/map_tree/display.rs
blob: 65302e1ec92e6054cdc9b7b801527d987b60c10d (plain) (tree)









































































                                                                                            


                                  










                                                                       
use std::fmt::Display;

use crate::mapping::{
    map_tree::{Node, NodeValue},
    MapKey,
};

use super::MappingTree;

impl Display for MappingTree {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        fn write_node(
            f: &mut std::fmt::Formatter<'_>,
            node: &Node,
            indention: String,
            location: Vec<MapKey>,
            is_last: bool,
            is_root: bool,
        ) -> std::fmt::Result {
            let node_value = match &node.value {
                NodeValue::Parent { children: _ } => "<Parent>".to_owned(),
                NodeValue::Child { path, extandable } => {
                    path.to_owned() + if *extandable { " [exten.]" } else { " [stop]" }
                }
            };

            let new_idention = indention.clone()
                + if is_root {
                    ""
                } else {
                    match is_last {
                        true => "    ",
                        false => "│   ",
                    }
                };

            let bullet = match is_last {
                true => String::from("└── "),
                false => String::from("├── "),
            };

            if is_root {
                write!(f, ": {}\n", node_value)?;
            } else {
                write!(
                    f,
                    "{}{}\x1b[1;33m{}\x1b[0m: {}\n",
                    indention,
                    bullet,
                    MapKey::display(&location),
                    node_value,
                )?;
            };

            match &node.value {
                NodeValue::Parent { children } => {
                    let mut children_vec: Vec<(&MapKey, &Node)> = children.iter().collect();
                    children_vec.sort_by(|(a, _), (b, _)| a.key.cmp(&b.key));

                    let mut counter = 1;
                    for (key, child) in &children_vec {
                        let mut new_location = location.clone();
                        new_location.push((*key).to_owned());

                        write_node(
                            f,
                            child,
                            new_idention.clone(),
                            new_location.clone(),
                            counter == children_vec.len(),
                            false,
                        )?;
                        counter += 1;
                    }
                }
                NodeValue::Child {
                    path: _,
                    extandable: _,
                } => {
                    // Do nothing and stop the recursion
                }
            }

            Ok(())
        }

        write_node(f, &self.root, String::new(), vec![], false, true)?;

        Ok(())
    }
}