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 | |
parent | feat(pkgs/lf-make-map): Init (diff) | |
download | 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')
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs | 107 | ||||
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs | 145 |
2 files changed, 170 insertions, 82 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(()) + } +} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs index 7de1ca5d..d05d3417 100644 --- a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs +++ b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + fmt::Display, + path::{Path, PathBuf}, +}; use log::debug; @@ -11,15 +14,42 @@ pub struct Mapping { pub keys: usize, - pub key: String, + pub key: Vec<MapKey>, } + +#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Hash, Eq)] +pub struct MapKey { + value: String, +} + +impl MapKey { + pub fn new(value: String) -> Self { + Self { value } + } + pub fn display(values: &[Self]) -> String { + values.iter().map(|value| value.value.clone()).collect() + } +} + +impl Display for MapKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.value) + } +} + +impl Display for Mapping { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.raw_path.display()) + } +} + impl Mapping { pub fn new(home_path: &Path, initial_path: PathBuf) -> Mapping { let raw_path = initial_path .strip_prefix(home_path) .expect("Must always be under the `home_path`"); - let key = Self::path_to_key(raw_path.to_str().expect("Should be a valid &str")); + let key = Self::path_to_keys(raw_path.to_str().expect("Should be a valid &str")); Self { raw_path: raw_path.to_owned(), @@ -28,71 +58,64 @@ impl Mapping { } } - fn path_to_key(path: &str) -> String { - let key: String = path - .split('/') - .map(|part| part.chars().nth(0).expect("Must have a first element")) - .collect(); - debug!("'{}' -> '{}'", path, key); + fn path_to_keys(path: &str) -> Vec<MapKey> { + let key: Vec<MapKey> = path.split('/').map(Self::part_path_to_key).collect(); + debug!("Will insert: '{}' -> '{}'", path, MapKey::display(&key)); key } -} -pub fn gen_hot_key(path: &Path, base_path: &Path, amount_of_chars: usize) -> String { - let path_filename_as_str = path - .file_name() - .expect("All paths here should have a file name") - .to_str() - .expect("The OSstr should be convertible"); - - let mut return_val = String::from("g"); - if path != base_path { - return_val.push( - base_path - .file_name() - .expect("All paths here should have a file name") - .to_str() - .expect("The OSstr should be convertible") - .chars() - .nth(0) - .expect("All names should have a first char"), - ); - } - if path_filename_as_str.contains("_") { - path_filename_as_str.split("_").for_each(|a| { - return_val.push( - a.chars() - .nth(0) - .expect("All names should have a first char"), - ) - }); - } else { - if path == base_path { - return_val.push( - path_filename_as_str - .chars() - .nth(0) - .expect("All names should have a first char"), - ); + fn part_path_to_key(part: &str) -> MapKey { + let value = if part.contains('_') { + part.split('_').filter_map(|ch| ch.chars().nth(0)).collect() + } else if part.contains('-') { + part.split('-').filter_map(|ch| ch.chars().nth(0)).collect() } else { - for a in 0..amount_of_chars { - return_val.push(if let Some(b) = path_filename_as_str.chars().nth(a) { - b - } else { - path_filename_as_str - .chars() - .nth(0) - .expect("All names should have a first char") - }); - } - } - } - if path == base_path { - return_val.push('.'); + part.chars() + .nth(0) + .expect("Must have a first element") + .to_string() + }; + MapKey::new(value) } - return_val } +// pub fn gen_hot_key(path: &Path, base_path: &Path, amount_of_chars: usize) -> String { +// let mut return_val = String::from("g"); +// if path_filename_as_str.contains("_") { +// path_filename_as_str.split("_").for_each(|a| { +// return_val.push( +// a.chars() +// .nth(0) +// .expect("All names should have a first char"), +// ) +// }); +// } else { +// if path == base_path { +// return_val.push( +// path_filename_as_str +// .chars() +// .nth(0) +// .expect("All names should have a first char"), +// ); +// } else { +// for a in 0..amount_of_chars { +// return_val.push(if let Some(b) = path_filename_as_str.chars().nth(a) { +// b +// } else { +// path_filename_as_str +// .chars() +// .nth(0) +// .expect("All names should have a first char") +// }); +// } +// } +// } +// if path == base_path { +// return_val.push('.'); +// } +// return_val +// } + #[cfg(test)] mod tests { use super::*; |