YTBN-Graphing-Software/parsing/src/autocomplete_hashmap.rs
Simon Gardling b37a6223bc updated
2023-03-07 10:05:37 -05:00

84 lines
2.2 KiB
Rust

use core::cmp::Ordering;
use std::collections::HashSet;
/// https://www.dotnetperls.com/sort-rust
fn compare_len_reverse_alpha(a: &String, b: &String) -> Ordering {
match a.len().cmp(&b.len()) {
Ordering::Equal => b.cmp(a),
order => order,
}
}
/// Generates hashmap (well really a vector of tuple of strings that are then turned into a hashmap by phf)
#[allow(dead_code)]
pub fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
let mut seen = HashSet::new();
let tuple_list_1: Vec<(String, String)> = data
.iter()
.map(|e| e.to_string() + "(")
.flat_map(|func| all_possible_splits(func, &mut seen))
.collect();
let keys: Vec<&String> = tuple_list_1.iter().map(|(a, _)| a).collect();
let mut output: Vec<(String, String)> = Vec::new();
let mut seen_3: HashSet<String> = HashSet::new();
for (key, value) in tuple_list_1.iter() {
if seen_3.contains(key) {
continue;
}
seen_3.insert(key.clone());
let count_keys = keys.iter().filter(|a| a == &&key).count();
match count_keys.cmp(&1usize) {
Ordering::Less => {
panic!("Number of values for {key} is 0!");
}
Ordering::Greater => {
let mut multi_data = tuple_list_1
.iter()
.filter(|(a, _)| a == key)
.map(|(_, b)| b)
.collect::<Vec<&String>>();
multi_data.sort_unstable_by(|a, b| compare_len_reverse_alpha(a, b));
output.push((key.clone(), format!("Hint::Many(&{:?})", multi_data)));
}
Ordering::Equal => output.push((key.clone(), format!(r#"Hint::Single("{}")"#, value))),
}
}
// sort
output.sort_unstable_by(|a, b| {
let new_a = format!(r#"("{}", {})"#, a.0, a.1);
let new_b = format!(r#"("{}", {})"#, b.0, b.1);
compare_len_reverse_alpha(&new_b, &new_a)
});
output
}
/// Returns a vector of all possible splitting combinations of a strings
#[allow(dead_code)]
fn all_possible_splits(
func: String, seen: &mut HashSet<(String, String)>,
) -> Vec<(String, String)> {
(1..func.len())
.map(|i| {
let (first, last) = func.split_at(i);
(first.to_string(), last.to_string())
})
.flat_map(|(first, last)| {
if seen.contains(&(first.clone(), last.clone())) {
return None;
}
seen.insert((first.to_string(), last.to_string()));
Some((first, last))
})
.collect::<Vec<(String, String)>>()
}