use std::collections::HashMap;
use crate::key::KeyEvent;
#[derive(Debug, Clone)]
pub struct Binding<A> {
pub action: A,
pub desc: String,
pub recursive: bool,
}
pub(crate) struct TrieNode<A> {
pub(crate) action: Option<Binding<A>>,
pub(crate) children: HashMap<KeyEvent, TrieNode<A>>,
}
impl<A> Default for TrieNode<A> {
fn default() -> Self {
Self {
action: None,
children: HashMap::new(),
}
}
}
impl<A: Clone> TrieNode<A> {
pub(crate) fn insert(&mut self, events: &[KeyEvent], binding: Binding<A>) {
if events.is_empty() {
self.action = Some(binding);
return;
}
let child = self.children.entry(events[0]).or_default();
child.insert(&events[1..], binding);
}
pub(crate) fn remove(&mut self, events: &[KeyEvent]) -> bool {
if events.is_empty() {
let had = self.action.is_some();
self.action = None;
return had;
}
if let Some(child) = self.children.get_mut(&events[0]) {
let removed = child.remove(&events[1..]);
if child.action.is_none() && child.children.is_empty() {
self.children.remove(&events[0]);
}
removed
} else {
false
}
}
pub(crate) fn lookup(&self, events: &[KeyEvent]) -> Option<&Binding<A>> {
if events.is_empty() {
return self.action.as_ref();
}
self.children.get(&events[0])?.lookup(&events[1..])
}
pub(crate) fn has_prefix(&self, events: &[KeyEvent]) -> bool {
if events.is_empty() {
return !self.children.is_empty();
}
match self.children.get(&events[0]) {
Some(child) => child.has_prefix(&events[1..]),
None => false,
}
}
pub(crate) fn children_of<'a>(
&'a self,
prefix: &[KeyEvent],
) -> Vec<(&'a KeyEvent, &'a Binding<A>)> {
if prefix.is_empty() {
return self
.children
.iter()
.filter_map(|(k, node)| node.action.as_ref().map(|b| (k, b)))
.collect();
}
match self.children.get(&prefix[0]) {
Some(child) => child.children_of(&prefix[1..]),
None => vec![],
}
}
}