1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::collections::HashMap;
use std::io;
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use crate::{EventHandleFn, ExitCode, Handler, Result};
pub struct KeyBind<S> {
pub event_mapping: HashMap<Event, Box<EventHandleFn<S>>>,
pub handle_input: Option<Box<EventHandleFn<S>>>,
pub handle_resize: Option<Box<EventHandleFn<S>>>,
}
impl<S> KeyBind<S> {
pub fn assign<I>(&mut self, items: I)
where
I: IntoIterator<Item = (Event, Box<EventHandleFn<S>>)>,
{
for (_, elem) in items.into_iter().enumerate() {
self.event_mapping.insert(elem.0, elem.1);
}
}
}
impl<S: 'static> Handler<S> for KeyBind<S> {
fn handle(
&mut self,
ev: Event,
out: &mut io::Stdout,
state: &mut S,
) -> Result<Option<ExitCode>> {
match self.event_mapping.get(&ev) {
Some(handle) => handle(None, None, out, state),
None => match ev {
Event::Resize(x, y) => match &self.handle_resize {
Some(func) => (func)(Some((x, y)), None, out, state),
None => Ok(None),
},
Event::Key(KeyEvent {
code: KeyCode::Char(ch),
modifiers: KeyModifiers::NONE,
})
| Event::Key(KeyEvent {
code: KeyCode::Char(ch),
modifiers: KeyModifiers::SHIFT,
}) => match &self.handle_input {
Some(func) => (func)(None, Some(ch), out, state),
None => Ok(None),
},
_ => Ok(None),
},
}
}
}
#[cfg(test)]
mod test {
use super::{io, EventHandleFn, HashMap, KeyBind};
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use std::any::Any;
#[test]
fn assign() {
let mut b = KeyBind::<Box<dyn Any>> {
event_mapping: HashMap::default(),
handle_input: None,
handle_resize: None,
};
b.assign(vec![(
Event::Key(KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::NONE,
}),
Box::new(|_, _, _: &mut io::Stdout, _: &mut Box<dyn Any>| Ok(Some(0)))
as Box<EventHandleFn<Box<dyn Any>>>,
)]);
assert_eq!(b.event_mapping.len(), 1);
}
}