about summary refs log tree commit diff stats
path: root/sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs')
-rw-r--r--sys/nixpkgs/pkgs/lf-make-map/src/mapping/mod.rs179
1 files changed, 87 insertions, 92 deletions
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 8bf6bbe0..129e9673 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::{fmt::Display, hash::Hash};
+use std::{
+    fmt::{Display, Write},
+    hash::Hash,
+};
 
 use log::debug;
 
@@ -7,7 +10,7 @@ pub mod map_tree;
 
 #[derive(Clone, Debug, Eq)]
 pub struct MapKey {
-    pub key: String,
+    pub key: char,
 
     resolution: usize,
 
@@ -28,29 +31,23 @@ impl PartialEq for MapKey {
 }
 
 impl MapKey {
-    pub fn new_from_part_path(part_path: &str, resolution: usize) -> Self {
+    pub fn new_from_part_path(part_path: &str, resolution: usize) -> Vec<Self> {
         let key = Self::part_path_to_key(&part_path, resolution);
-        Self {
-            key,
-            resolution,
-            part_path: part_path.to_owned(),
-        }
-    }
 
-    pub fn increment(&mut self) {
-        if self.resolution < self.part_path.len() {
-            self.resolution += 1;
-            self.key = Self::part_path_to_key(&self.part_path, self.resolution);
-        } else {
-            let last_char = self.key.chars().last().expect("A last value exists");
-            self.key.push(last_char);
-        }
+        key.chars()
+            .map(|ch| Self {
+                key: ch,
+                resolution,
+                part_path: part_path.to_owned(),
+            })
+            .collect()
     }
 
-    pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec<MapKey> {
+    pub fn new_ones_from_path(path: &str, number_of_chars: usize) -> Vec<Self> {
         let key: Vec<MapKey> = path
             .split('/')
             .map(|part| Self::new_from_part_path(part, number_of_chars))
+            .flatten()
             .collect();
 
         debug!(
@@ -61,94 +58,92 @@ impl MapKey {
         key
     }
 
+    pub fn increment(&self, target_resolution: usize) -> Vec<Self> {
+        let new_resolution = target_resolution;
+
+        // debug!("Incrementing: '{}' ('{}')", &self, &self.part_path);
+
+        let added_chars = if new_resolution < self.part_path.len() {
+            MapKey::part_path_to_key(&self.part_path, new_resolution)
+        } else {
+            let mut generated_chars =
+                MapKey::part_path_to_key(&self.part_path, self.part_path.len());
+
+            generated_chars.extend(
+                (0..(new_resolution - self.part_path.len()))
+                    .into_iter()
+                    .map(|_| self.part_path.chars().last().expect("This will exists")),
+            );
+
+            generated_chars
+        };
+        assert_eq!(added_chars.len(), new_resolution,);
+
+        let part_path = self.part_path.clone();
+        let output: Vec<Self> = added_chars
+            .chars()
+            .enumerate()
+            .map(|(res, ch)| MapKey {
+                key: ch,
+                resolution: res + 1,
+                part_path: part_path.clone(),
+            })
+            .collect();
+
+        // debug!("Finished increment: '{}' ('{}')", MapKey::display(&output), output[0].part_path);
+        output
+    }
+
     pub fn display(values: &[Self]) -> String {
         values.iter().map(|value| value.key.clone()).collect()
     }
     fn part_path_to_key(part: &str, number_of_chars: usize) -> String {
+        fn make(pat: char, part: &str, number_of_chars: usize) -> String {
+            let mut acc = String::new();
+
+            let mut last_working = None;
+            for i in 0..number_of_chars {
+                for str in part.split(pat) {
+                    if acc.len() != number_of_chars {
+                        acc.push(match str.chars().nth(i) {
+                            Some(ch) => ch,
+                            None => {
+                                if let Some(last) = last_working {
+                                    str.chars().nth(last).expect("This should always exist")
+                                } else {
+                                    last_working = Some(i - 1);
+                                    str.chars().nth(i - 1).expect("This should always exist")
+                                }
+                            }
+                        })
+                    }
+                }
+            }
+
+            acc
+        }
+
         let value = if part.contains('_') {
-            part.split('_')
-                .map(|ch| ch.chars().take(number_of_chars).collect::<Vec<char>>())
-                .flatten()
-                .collect()
+            make('_', part, number_of_chars)
         } else if part.contains('-') {
-            part.split('-')
-                .map(|ch| ch.chars().take(number_of_chars).collect::<Vec<char>>())
-                .flatten()
-                .collect()
+            make('-', part, number_of_chars)
         } else {
             part.chars().take(number_of_chars).collect::<String>()
         };
+
+        assert_eq!(
+            value.len(),
+            number_of_chars,
+            "'{}' is not {}",
+            value,
+            number_of_chars
+        );
         value
     }
 }
 
 impl Display for MapKey {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.write_str(&self.key)
-    }
-}
-
-// 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::*;
-    #[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());
+        f.write_char(self.key)
     }
 }