Skip to content

Commit e063091

Browse files
authored
Add is_* and as_* methods to the event enums (#949)
* Add is_ and as_ methods to the event enums Often application code only cares about a small subset of possible events. These methods make it simpler to write code which checks whether an event is a particular event type or converts events into the specific type (returning an Option). This can help simplify some nested match blocks. E.g.: ```rust match event { Event::Key(key) if key.kind == KeyEventKind::Press => { ... } } ``` becomes: ```rust if let Some(key) = event.as_key_press() { ... } ``` Similar flexible methods are aded across all the event enums: - `Event::is_focus_gained()` - `Event::is_focus_lost()` - `Event::is_key()` - `Event::is_mouse()` - `Event::is_paste()` - `Event::is_resize()` - `Event::is_key_press()` - `Event::as_key_press() -> Option<&KeyEvent>` - `MouseEventKind::is_*()` - `MouseButton::is_*()` - `KeyEventKind::is_*()` - `KeyEvent::is_press()` - `KeyEvent::is_release()` - `KeyEvent::is_repeat()` - `KeyCode::is_*()` - `KeyCode::is_function_key(n)` - `KeyCode::is_char(c)` - `KeyCode::as_char() -> Option<char>` - `KeyCode::is_media_key(media)` - `KeyCode::is_modifier(modifier)` - add is_key_release() and is_key_repeat() checks - add as_key_event() - rename as_key_press() to as_key_press_event() - add as_key_repeat_event() - add as_key_release_event() - add as_mouse_event() - add as_paste_event() - more tests - update event-match and key-display examples
1 parent 1bcfa97 commit e063091

File tree

4 files changed

+450
-55
lines changed

4 files changed

+450
-55
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use-dev-tty = ["filedescriptor", "rustix/process"]
4646

4747
[dependencies]
4848
bitflags = { version = "2.3" }
49+
derive_more = { version = "1.0.0", features = ["is_variant"] }
4950
document-features = "0.2.10"
5051
futures-core = { version = "0.3", optional = true, default-features = false }
5152
parking_lot = "0.12"

examples/event-match-modifiers.rs

+33-34
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,42 @@
44
55
use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
66

7-
fn match_event(read_event: Event) {
8-
match read_event {
9-
// Match one one modifier:
10-
Event::Key(KeyEvent {
11-
modifiers: KeyModifiers::CONTROL,
12-
code,
13-
..
14-
}) => {
15-
println!("Control + {:?}", code);
16-
}
17-
Event::Key(KeyEvent {
18-
modifiers: KeyModifiers::SHIFT,
19-
code,
20-
..
21-
}) => {
22-
println!("Shift + {:?}", code);
23-
}
24-
Event::Key(KeyEvent {
25-
modifiers: KeyModifiers::ALT,
26-
code,
27-
..
28-
}) => {
29-
println!("Alt + {:?}", code);
30-
}
7+
fn match_event(event: Event) {
8+
if let Some(key) = event.as_key_press_event() {
9+
match key {
10+
KeyEvent {
11+
modifiers: KeyModifiers::CONTROL,
12+
code,
13+
..
14+
} => {
15+
println!("Control + {:?}", code);
16+
}
17+
KeyEvent {
18+
modifiers: KeyModifiers::SHIFT,
19+
code,
20+
..
21+
} => {
22+
println!("Shift + {:?}", code);
23+
}
24+
KeyEvent {
25+
modifiers: KeyModifiers::ALT,
26+
code,
27+
..
28+
} => {
29+
println!("Alt + {:?}", code);
30+
}
3131

32-
// Match on multiple modifiers:
33-
Event::Key(KeyEvent {
34-
code, modifiers, ..
35-
}) => {
36-
if modifiers == (KeyModifiers::ALT | KeyModifiers::SHIFT) {
37-
println!("Alt + Shift {:?}", code);
38-
} else {
39-
println!("({:?}) with key: {:?}", modifiers, code)
32+
// Match on multiple modifiers:
33+
KeyEvent {
34+
code, modifiers, ..
35+
} => {
36+
if modifiers == (KeyModifiers::ALT | KeyModifiers::SHIFT) {
37+
println!("Alt + Shift {:?}", code);
38+
} else {
39+
println!("({:?}) with key: {:?}", modifiers, code)
40+
}
4041
}
4142
}
42-
43-
_ => {}
4443
}
4544
}
4645

examples/key-display.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
88
use std::io;
99

10-
use crossterm::event::{KeyEventKind, KeyModifiers};
10+
use crossterm::event::KeyModifiers;
1111
use crossterm::{
12-
event::{read, Event, KeyCode},
12+
event::{read, KeyCode},
1313
terminal::{disable_raw_mode, enable_raw_mode},
1414
};
1515

@@ -29,20 +29,17 @@ fn main() -> io::Result<()> {
2929
}
3030

3131
fn print_events() -> io::Result<()> {
32-
loop {
33-
let event = read()?;
34-
match event {
35-
Event::Key(event) if event.kind == KeyEventKind::Press => {
36-
print!("Key pressed: ");
37-
if event.modifiers != KeyModifiers::NONE {
38-
print!("{}+", event.modifiers);
39-
}
40-
println!("{}\r", event.code);
41-
if event.code == KeyCode::Esc {
42-
break;
43-
}
44-
}
45-
_ => {}
32+
while let Ok(event) = read() {
33+
let Some(event) = event.as_key_press_event() else {
34+
continue;
35+
};
36+
let modifier = match event.modifiers {
37+
KeyModifiers::NONE => "".to_string(),
38+
_ => format!("{:}+", event.modifiers),
39+
};
40+
println!("Key pressed: {modifier}{code}\r", code = event.code);
41+
if event.code == KeyCode::Esc {
42+
break;
4643
}
4744
}
4845
Ok(())

0 commit comments

Comments
 (0)