From b496a2b2616209ce679abd289567c34782275b53 Mon Sep 17 00:00:00 2001 From: Geoff Shannon Date: Thu, 31 Jan 2019 14:18:43 -0800 Subject: [PATCH] Add an example showing async usage with tokio --- Cargo.toml | 3 +++ examples/async.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 examples/async.rs diff --git a/Cargo.toml b/Cargo.toml index b9c9781730..b9e4e29fa7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,10 @@ winapi = { version = "0.3", features = ["consoleapi", "handleapi", "minwindef", env_logger = "0.6" tempdir = "0.3" assert_matches = "1.2" +futures = "0.1" +tokio = "0.1" [features] default = ["with-dirs"] with-dirs = ["dirs"] + diff --git a/examples/async.rs b/examples/async.rs new file mode 100644 index 0000000000..7eb8aa62c1 --- /dev/null +++ b/examples/async.rs @@ -0,0 +1,63 @@ +use std::sync::mpsc as sync_mpsc; +use std::thread; +use std::time::Duration; + +use rustyline::error::ReadlineError; +use rustyline::Editor; + +use futures::future::Future; +use futures::stream::Stream; + +use tokio::sync::mpsc as async_mpsc; + +fn main() { + let timeout = Duration::from_millis(10); + + let (mut stdin_tx, stdin_rx) = async_mpsc::unbounded_channel(); + let (stdout_tx, stdout_rx) = sync_mpsc::channel(); + + let mut editor = Editor::<()>::new(); + + let _thread = thread::spawn(move || loop { + // Standard usage of the Rustyline editor + let line = editor.readline("> "); + + // Decide whether we should quit, otherwise we loop forever. + let quit = match &line { + Err(ReadlineError::Interrupted) => true, + Err(ReadlineError::Eof) => true, + _ => false, + }; + + // Send read lines into the async system + stdin_tx.try_send(line).expect("failed to send"); + + // Block for a moment to give the async code a chance to run + match stdout_rx.recv_timeout(timeout) { + Ok(msg) => println!("{}", msg), + Err(sync_mpsc::RecvTimeoutError::Timeout) => (), + Err(sync_mpsc::RecvTimeoutError::Disconnected) => break, + } + + if quit { + break; + } + }); + + let read_all = stdin_rx.for_each(move |line| { + // Handle the data sent by the Editor thread + let message = match line { + Ok(line) => format!("Line: {}", line), + Err(ReadlineError::Interrupted) => format!("CTRL-C"), + Err(ReadlineError::Eof) => format!("CTRL-D"), + Err(err) => format!("Error: {:?}", err), + }; + + // Communicate back data to print to the user. + stdout_tx.send(message).ok(); + + Ok(()) + }); + + tokio::run(read_all.map_err(|_| ())); +}