use crate::trie::{KeyTrie, KeyTrieNode};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WhichKeyEntry {
pub key: String,
pub description: String,
pub is_group: bool,
}
impl KeyTrieNode {
pub fn which_key_entries(&self) -> Vec {
let mut groups = Vec::new();
let mut leaves = Vec::new();
for (key, trie) in &self.map {
match trie {
KeyTrie::Node(node) => {
groups.push(WhichKeyEntry {
key: key.to_string(),
description: node.name.clone(),
is_group: true,
});
}
KeyTrie::Leaf(leaf) => {
leaves.push(WhichKeyEntry {
key: key.to_string(),
description: leaf.description.clone().unwrap_or_default(),
is_group: false,
});
}
}
}
groups.sort_by(|a, b| a.key.cmp(&b.key));
leaves.sort_by(|a, b| a.key.cmp(&b.key));
groups.extend(leaves);
groups
}
}
#[cfg(test)]
mod tests {
use crate::trie::KeyTrie;
#[test]
fn test_empty_node() {
let trie: KeyTrie<&str> = KeyTrie::new("root");
if let KeyTrie::Node(node) = trie {
let entries = node.which_key_entries();
assert!(entries.is_empty());
}
}
#[test]
fn test_leaves_only_sorted() {
let mut trie: KeyTrie<&str> = KeyTrie::new("root");
trie.bind_desc("c", "action_c", "C action").unwrap();
trie.bind_desc("a", "action_a", "A action").unwrap();
trie.bind_desc("b", "action_b", "B action").unwrap();
if let KeyTrie::Node(node) = trie {
let entries = node.which_key_entries();
assert_eq!(entries.len(), 3);
assert_eq!(entries[0].key, "a");
assert_eq!(entries[1].key, "b");
assert_eq!(entries[2].key, "c");
}
}
#[test]
fn test_groups_before_leaves() {
let mut trie: KeyTrie<&str> = KeyTrie::new("root");
trie.bind_desc("z", "action", "Z action").unwrap();
trie.group("g", "goto", |node| {
node.bind("g", "goto_top")?;
Ok(())
})
.unwrap();
trie.bind_desc("a", "action", "A action").unwrap();
if let KeyTrie::Node(node) = trie {
let entries = node.which_key_entries();
assert_eq!(entries.len(), 3);
assert!(entries[0].is_group);
assert_eq!(entries[0].key, "g");
assert!(!entries[1].is_group);
assert_eq!(entries[1].key, "a");
assert!(!entries[2].is_group);
assert_eq!(entries[2].key, "z");
}
}
#[test]
fn test_descriptions_populated() {
let mut trie: KeyTrie<&str> = KeyTrie::new("root");
trie.bind_desc("j", "down", "Move down").unwrap();
trie.group("g", "goto", |_| Ok(())).unwrap();
if let KeyTrie::Node(node) = trie {
let entries = node.which_key_entries();
let group = entries.iter().find(|e| e.key == "g").unwrap();
assert_eq!(group.description, "goto");
assert!(group.is_group);
let leaf = entries.iter().find(|e| e.key == "j").unwrap();
assert_eq!(leaf.description, "Move down");
assert!(!leaf.is_group);
}
}
}