| //! Demonstrates how to read events asynchronously with tokio. | |
| //! | |
| //! cargo run --features="event-stream" --example event-stream-tokio | |
| use std::{ | |
| io::{stdout, Write}, | |
| time::Duration, | |
| }; | |
| use futures::{future::FutureExt, select, StreamExt}; | |
| use futures_timer::Delay; | |
| use crossterm::{ | |
| cursor::position, | |
| event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream, KeyCode}, | |
| execute, | |
| terminal::{disable_raw_mode, enable_raw_mode}, | |
| Result, | |
| }; | |
| const HELP: &str = r#"EventStream based on futures_util::Stream with tokio | |
| - Keyboard, mouse and terminal resize events enabled | |
| - Prints "." every second if there's no event | |
| - Hit "c" to print current cursor position | |
| - Use Esc to quit | |
| "#; | |
| async fn print_events() { | |
| let mut reader = EventStream::new(); | |
| loop { | |
| let mut delay = Delay::new(Duration::from_millis(1_000)).fuse(); | |
| let mut event = reader.next().fuse(); | |
| select! { | |
| _ = delay => { println!(".\r"); }, | |
| maybe_event = event => { | |
| match maybe_event { | |
| Some(Ok(event)) => { | |
| println!("Event::{:?}\r", event); | |
| if event == Event::Key(KeyCode::Char('c').into()) { | |
| println!("Cursor position: {:?}\r", position()); | |
| } | |
| if event == Event::Key(KeyCode::Esc.into()) { | |
| break; | |
| } | |
| } | |
| Some(Err(e)) => println!("Error: {:?}\r", e), | |
| None => break, | |
| } | |
| } | |
| }; | |
| } | |
| } | |
| #[tokio::main] | |
| async fn main() -> Result<()> { | |
| println!("{}", HELP); | |
| enable_raw_mode()?; | |
| let mut stdout = stdout(); | |
| execute!(stdout, EnableMouseCapture)?; | |
| print_events().await; | |
| execute!(stdout, DisableMouseCapture)?; | |
| disable_raw_mode() | |
| } |