Skip to content
This repository has been archived by the owner on Oct 22, 2019. It is now read-only.

Commit

Permalink
Refactor unix (a)sync readers
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Vojta <rvojta@me.com>
  • Loading branch information
zrzka committed Oct 9, 2019
1 parent bb53032 commit 0efd4c1
Show file tree
Hide file tree
Showing 5 changed files with 781 additions and 449 deletions.
94 changes: 94 additions & 0 deletions examples/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#![allow(dead_code)]
use std::io::{stdout, Write};

use crossterm_input::{
InputEvent, InternalEvent, KeyEvent, MouseEvent, RawScreen, Result, TerminalInput,
};

// Sample implementation for crossterm_cursor & pos_raw
fn pos_raw() -> Result<(u16, u16)> {
let input = TerminalInput::new();
let mut reader = input.read_sync();

// Write command
let mut stdout = stdout();
stdout.write_all(b"\x1B[6n")?;
stdout.flush()?;

loop {
if let Some(InputEvent::Internal(InternalEvent::CursorPosition(x, y))) = reader.next() {
return Ok((x, y));
}
}
}

fn async_test() -> Result<()> {
let input = TerminalInput::new();
let _raw = RawScreen::into_raw_mode()?;

let mut reader = input.read_async();

input.enable_mouse_mode()?;

loop {
if let Some(event) = reader.next() {
match event {
InputEvent::Keyboard(KeyEvent::Esc) => break,
InputEvent::Keyboard(KeyEvent::Char('c')) => println!("Cursor: {:?}", pos_raw()),
InputEvent::Mouse(mouse) => {
match mouse {
MouseEvent::Press(_, x, y) => println!("Press: {}x{}", x, y),
MouseEvent::Hold(x, y) => println!("Move: {}x{}", x, y),
MouseEvent::Release(x, y) => println!("Release: {}x{}", x, y),
_ => {}
};
}
InputEvent::Internal(_) => {}
e => {
println!("Event: {:?}", e);
}
};
}
std::thread::sleep(std::time::Duration::from_millis(100));
println!(".");
}

input.disable_mouse_mode()?;
Ok(())
}

fn sync_test() -> Result<()> {
let input = TerminalInput::new();
let _raw = RawScreen::into_raw_mode()?;
input.enable_mouse_mode()?;

let mut reader = input.read_sync();
loop {
if let Some(event) = reader.next() {
match event {
InputEvent::Keyboard(KeyEvent::Esc) => break,
InputEvent::Keyboard(KeyEvent::Char('c')) => println!("Cursor: {:?}", pos_raw()),
InputEvent::Mouse(mouse) => {
match mouse {
MouseEvent::Press(_, x, y) => println!("Press: {}x{}", x, y),
MouseEvent::Hold(x, y) => println!("Move: {}x{}", x, y),
MouseEvent::Release(x, y) => println!("Release: {}x{}", x, y),
_ => {}
};
}
InputEvent::Internal(_) => {}
e => {
println!("Event: {:?}", e);
}
};
}
println!(".");
}
input.disable_mouse_mode()?;
Ok(())
}

fn main() -> Result<()> {
// async_test()
sync_test()
}
29 changes: 29 additions & 0 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! A module that contains all the actions related to reading input from the terminal.
//! Like reading a line, reading a character and reading asynchronously.
use std::io;

use crossterm_utils::Result;

// TODO Create a new common AsyncReader structure (like TerminalCursor, TerminalInput, ...).
Expand All @@ -24,6 +26,33 @@ pub(crate) mod windows;
/// This trait is implemented for Windows and UNIX systems.
/// Unix is using the 'TTY' and windows is using 'libc' C functions to read the input.
pub(crate) trait Input {
/// Reads one line from the user input and strips the new line character(s).
///
/// This function **does not work** when the raw mode is enabled (see the
/// [`crossterm_screen`](https://docs.rs/crossterm_screen/) crate documentation
/// to learn more). You should use the
/// [`read_async`](struct.TerminalInput.html#method.read_async),
/// [`read_until_async`](struct.TerminalInput.html#method.read_until_async)
/// or [`read_sync`](struct.TerminalInput.html#method.read_sync) method if the
/// raw mode is enabled.
///
/// # Examples
///
/// ```no_run
/// let input = crossterm_input::input();
/// match input.read_line() {
/// Ok(s) => println!("string typed: {}", s),
/// Err(e) => println!("error: {}", e),
/// }
/// ```
fn read_line(&self) -> Result<String> {
let mut rv = String::new();
io::stdin().read_line(&mut rv)?;
let len = rv.trim_end_matches(&['\r', '\n'][..]).len();
rv.truncate(len);
Ok(rv)
}

/// Read one character from the user input
fn read_char(&self) -> Result<char>;
/// Read the input asynchronously from the user.
Expand Down
Loading

0 comments on commit 0efd4c1

Please sign in to comment.