diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-05 14:02:09 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-05 14:02:09 +0200 |
commit | 47e3b82d0f8c9c4abcaf8588764fa934446dbdc8 (patch) | |
tree | 807f4874f1b945b82c00ec5cd666b4173bd09aab /sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs | |
parent | feat(pkgs/lf-make-map): Init (diff) | |
download | nixos-config-47e3b82d0f8c9c4abcaf8588764fa934446dbdc8.tar.gz nixos-config-47e3b82d0f8c9c4abcaf8588764fa934446dbdc8.zip |
feat(pkgs/lf-make-map): Change the key to custom type and add visuals
Diffstat (limited to 'sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs')
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs | 107 |
1 files changed, 86 insertions, 21 deletions
diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs index 44165ed1..90296044 100644 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs +++ b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs @@ -1,6 +1,6 @@ -use std::collections::HashMap; +use std::{collections::HashMap, fmt::Display, path::PathBuf}; -use super::{error, Mapping}; +use super::{error, MapKey, Mapping}; /// A prefix tree pub struct MappingTree { @@ -9,33 +9,33 @@ pub struct MappingTree { #[derive(Clone)] pub struct Node { - children: HashMap<char, Node>, + children: HashMap<MapKey, Node>, value: Option<Mapping>, /// The key needed to get to this node - location: String, + location: Vec<MapKey>, } impl MappingTree { pub fn new() -> Self { Self { - root: Node::new(String::new(), None), + root: Node::new(vec![], None), } } /// Returns the node at the key, otherwise None - pub fn get(&self, key: &str) -> Option<&Node> { + pub fn get(&self, key: &[MapKey]) -> Option<&Node> { let mut current_node = &self.root; - for ch in key.chars() { + for ch in key.iter() { current_node = current_node.children.get(&ch)? } Some(current_node) } /// Returns the node at the key, otherwise None. The node can be changed - pub fn get_mut(&mut self, key: &str) -> Option<&mut Node> { + pub fn get_mut(&mut self, key: &[MapKey]) -> Option<&mut Node> { let mut current_node = &mut self.root; - for ch in key.chars() { + for ch in key.iter() { current_node = current_node.children.get_mut(&ch)? } @@ -43,9 +43,9 @@ impl MappingTree { } /// Returns the node at the key, otherwise the last node that matched. - pub fn try_get(&self, key: &str) -> &Node { + pub fn try_get(&self, key: &[MapKey]) -> &Node { let mut current_node = &self.root; - for ch in key.chars() { + for ch in key.iter() { if let Some(node) = current_node.children.get(&ch) { current_node = node; } else { @@ -56,20 +56,22 @@ impl MappingTree { current_node } - pub fn insert(&mut self, key: &str, mapping: Mapping) -> Result<(), error::Error> { + pub fn insert(&mut self, key: &[MapKey], mapping: Mapping) -> Result<(), error::Error> { let node = self.try_get(key).clone(); - if node.location.as_str() != key { - let needed_nodes_key = key.trim_start_matches(node.location.as_str()); - let needed_nodes_length = needed_nodes_key.chars().count(); + if node.location.as_slice() != key { + let needed_nodes_key = key + .strip_prefix(node.location.as_slice()) + .expect("The node's location is a prefix"); + let needed_nodes_length = needed_nodes_key.iter().count(); let mut current_node = self .get_mut(&node.location) .expect("This should always exists"); let mut current_location = node.location.clone(); - let mut counter = 0; + let mut counter = 1; - for ch in needed_nodes_key.chars() { - current_location.push(ch); + for ch in needed_nodes_key.iter() { + current_location.push(ch.to_owned()); let next_node = if counter == needed_nodes_length { Node::new(current_location.clone(), Some(mapping.clone())) @@ -77,7 +79,7 @@ impl MappingTree { Node::new(current_location.clone(), None) }; - current_node.children.insert(ch, next_node); + current_node.children.insert(ch.to_owned(), next_node); current_node = current_node .children .get_mut(&ch) @@ -85,7 +87,7 @@ impl MappingTree { counter += 1; } } else { - return Err(error::Error::NodeExits(key.to_owned())); + return Err(error::Error::NodeExits(MapKey::display(key))); } Ok(()) @@ -93,7 +95,7 @@ impl MappingTree { } impl Node { - pub fn new(location: String, mapping: Option<Mapping>) -> Self { + pub fn new(location: Vec<MapKey>, mapping: Option<Mapping>) -> Self { Self { children: HashMap::new(), location, @@ -101,3 +103,66 @@ impl Node { } } } + +impl Display for MappingTree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn write_node( + node: &Node, + indention: String, + has_parent: bool, + is_last: bool, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result { + let bullet = if has_parent { + if is_last { + String::from("└── ") + } else { + String::from("├── ") + } + } else { + String::new() + }; + + let node_value = if let Some(value) = &node.value { + value.to_string() + } else { + "[No Value]".to_owned() + }; + + let new_idention = if !has_parent { + String::new() + } else if is_last { + indention.replace('│', " ") + " " + } else { + indention.clone() + "│ " + }; + + write!( + f, + "{}{}\x1b[1;33m{}\x1b[0m: {}\n", + indention, + bullet, + MapKey::display(&node.location), + node_value, + )?; + + let value_length = node.children.len(); + let mut counter = 1; + + for child in node.children.values() { + if counter == value_length { + write_node(child, new_idention.clone(), true, true, f)?; + } else { + write_node(child, new_idention.clone(), true, false, f)?; + }; + counter += 1; + } + + Ok(()) + } + + write_node(&self.root, String::new(), false, false, f)?; + + Ok(()) + } +} |