about summary refs log tree commit diff stats
path: root/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-05 14:02:09 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-05-05 14:02:09 +0200
commit47e3b82d0f8c9c4abcaf8588764fa934446dbdc8 (patch)
tree807f4874f1b945b82c00ec5cd666b4173bd09aab /sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs
parentfeat(pkgs/lf-make-map): Init (diff)
downloadnixos-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.rs107
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(())
+    }
+}