diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-05 12:59:36 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-05-05 12:59:36 +0200 |
commit | 023b7cd0ada0cb153769bdcc931ef04512d125c4 (patch) | |
tree | 584315a010a9eccdd182e48801496ea4e226bfcb /sys/nixpkgs/pkgs/lf-make-map/src/mapping | |
parent | build(treewide): Update (diff) | |
download | nixos-config-023b7cd0ada0cb153769bdcc931ef04512d125c4.tar.gz nixos-config-023b7cd0ada0cb153769bdcc931ef04512d125c4.zip |
feat(pkgs/lf-make-map): Init
Diffstat (limited to '')
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/error.rs | 7 | ||||
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs | 103 | ||||
-rw-r--r-- | sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs | 122 |
3 files changed, 232 insertions, 0 deletions
diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/error.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/error.rs new file mode 100644 index 00000000..2a59ed64 --- /dev/null +++ b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("The node at key '{0}' already exists!")] + NodeExits(String), +} 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 new file mode 100644 index 00000000..44165ed1 --- /dev/null +++ b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/map_tree.rs @@ -0,0 +1,103 @@ +use std::collections::HashMap; + +use super::{error, Mapping}; + +/// A prefix tree +pub struct MappingTree { + root: Node, +} + +#[derive(Clone)] +pub struct Node { + children: HashMap<char, Node>, + value: Option<Mapping>, + + /// The key needed to get to this node + location: String, +} + +impl MappingTree { + pub fn new() -> Self { + Self { + root: Node::new(String::new(), None), + } + } + + /// Returns the node at the key, otherwise None + pub fn get(&self, key: &str) -> Option<&Node> { + let mut current_node = &self.root; + for ch in key.chars() { + 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> { + let mut current_node = &mut self.root; + for ch in key.chars() { + current_node = current_node.children.get_mut(&ch)? + } + + Some(current_node) + } + + /// Returns the node at the key, otherwise the last node that matched. + pub fn try_get(&self, key: &str) -> &Node { + let mut current_node = &self.root; + for ch in key.chars() { + if let Some(node) = current_node.children.get(&ch) { + current_node = node; + } else { + return current_node; + } + } + + current_node + } + + pub fn insert(&mut self, key: &str, 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(); + + 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; + + for ch in needed_nodes_key.chars() { + current_location.push(ch); + + let next_node = if counter == needed_nodes_length { + Node::new(current_location.clone(), Some(mapping.clone())) + } else { + Node::new(current_location.clone(), None) + }; + + current_node.children.insert(ch, next_node); + current_node = current_node + .children + .get_mut(&ch) + .expect("Was just inserted"); + counter += 1; + } + } else { + return Err(error::Error::NodeExits(key.to_owned())); + } + + Ok(()) + } +} + +impl Node { + pub fn new(location: String, mapping: Option<Mapping>) -> Self { + Self { + children: HashMap::new(), + location, + value: mapping, + } + } +} diff --git a/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs new file mode 100644 index 00000000..7de1ca5d --- /dev/null +++ b/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs @@ -0,0 +1,122 @@ +use std::path::{Path, PathBuf}; + +use log::debug; + +pub mod error; +pub mod map_tree; + +#[derive(Debug, Clone)] +pub struct Mapping { + pub raw_path: PathBuf, + + pub keys: usize, + + pub key: String, +} +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")); + + Self { + raw_path: raw_path.to_owned(), + keys: key.len(), + key, + } + } + + 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); + 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"), + ); + } 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::*; + #[test] + fn gen_hot_key_test() { + let gen1 = gen_hot_key( + Path::new("/home/dt/repos/java_script"), + Path::new("/home/dt/repos"), + 1, + ); + assert_eq!(gen1, "grjs".to_owned()); + } + #[test] + fn gen_hot_key_test_for_same_names() { + let gen1 = gen_hot_key(Path::new("/home/dt/repos/"), Path::new("/home/dt/repos"), 1); + assert_eq!(gen1, "gr.".to_owned()); + } + #[test] + fn gen_hot_key_test_for_non_underscore_name() { + let gen1 = gen_hot_key( + Path::new("/home/dt/repos/rust"), + Path::new("/home/dt/repos"), + 1, + ); + assert_eq!(gen1, "grr".to_owned()); + } +} |