From 05d28b4c5ab783403dbe8b6461178bdb215f5183 Mon Sep 17 00:00:00 2001 From: Zrzka Date: Wed, 18 Sep 2019 19:31:12 +0200 Subject: [PATCH] io::Result to crossterm::Result (#232) --- crossterm_cursor/src/sys/unix.rs | 4 +- crossterm_cursor/src/sys/winapi.rs | 25 ++--- crossterm_input/src/input.rs | 4 +- crossterm_input/src/input/input.rs | 4 +- crossterm_input/src/input/unix_input.rs | 2 +- crossterm_input/src/input/windows_input.rs | 20 ++-- crossterm_input/src/sys/unix.rs | 18 ++-- crossterm_screen/src/screen/alternate.rs | 10 +- crossterm_screen/src/screen/raw.rs | 12 ++- crossterm_screen/src/sys/unix.rs | 2 +- crossterm_screen/src/sys/winapi.rs | 6 +- crossterm_style/src/color.rs | 3 +- crossterm_style/src/winapi_color.rs | 3 +- crossterm_utils/src/command.rs | 3 +- crossterm_utils/src/error.rs | 15 --- crossterm_utils/src/sys/unix.rs | 14 +-- crossterm_utils/src/sys/winapi.rs | 5 +- examples/alternate_screen.rs | 19 ++-- examples/command.rs | 11 ++- examples/command_bar.rs | 108 ++++++++++----------- examples/cursor.rs | 39 ++++---- examples/input.rs | 4 +- examples/key_events.rs | 76 ++++++++------- examples/raw_mode.rs | 19 ++-- examples/style.rs | 23 +++-- examples/terminal.rs | 62 +++++------- 26 files changed, 238 insertions(+), 273 deletions(-) diff --git a/crossterm_cursor/src/sys/unix.rs b/crossterm_cursor/src/sys/unix.rs index 59bd047ee..dde5c164d 100644 --- a/crossterm_cursor/src/sys/unix.rs +++ b/crossterm_cursor/src/sys/unix.rs @@ -25,14 +25,14 @@ pub fn show_cursor(show_cursor: bool) -> Result<()> { Ok(()) } -pub fn pos() -> io::Result<(u16, u16)> { +pub fn pos() -> Result<(u16, u16)> { unix::into_raw_mode()?; let pos = pos_raw(); unix::disable_raw_mode()?; pos } -pub fn pos_raw() -> io::Result<(u16, u16)> { +pub fn pos_raw() -> Result<(u16, u16)> { // Where is the cursor? // Use `ESC [ 6 n`. let mut stdout = io::stdout(); diff --git a/crossterm_cursor/src/sys/winapi.rs b/crossterm_cursor/src/sys/winapi.rs index a0baab951..6a1f937ae 100644 --- a/crossterm_cursor/src/sys/winapi.rs +++ b/crossterm_cursor/src/sys/winapi.rs @@ -1,6 +1,6 @@ //! This module handles some logic for cursor interaction in the windows console. -use std::io::{self, Result}; +use std::io; use winapi::{ shared::minwindef::{FALSE, TRUE}, @@ -8,6 +8,7 @@ use winapi::{ um::winnt::HANDLE, }; +use crossterm_utils::Result; pub use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer}; #[cfg(windows)] @@ -32,7 +33,7 @@ pub struct Cursor { } impl Cursor { - pub fn new() -> io::Result { + pub fn new() -> Result { Ok(Cursor { screen_buffer: ScreenBuffer::from(Handle::new(HandleType::CurrentOutputHandle)?), }) @@ -44,25 +45,25 @@ impl Cursor { } /// Set the cursor position to the given x and y. Note that this is 0 based. - pub fn goto(&self, x: i16, y: i16) -> io::Result<()> { + pub fn goto(&self, x: i16, y: i16) -> Result<()> { if x < 0 || x >= ::max_value() { - return Err(io::Error::new( + Err(io::Error::new( io::ErrorKind::Other, format!( "Argument Out of Range Exception when setting cursor position to X: {}", x ), - )); + ))?; } if y < 0 || y >= ::max_value() { - return Err(io::Error::new( + Err(io::Error::new( io::ErrorKind::Other, format!( "Argument Out of Range Exception when setting cursor position to Y: {}", y ), - )); + ))?; } let position = COORD { X: x, Y: y }; @@ -72,14 +73,14 @@ impl Cursor { **self.screen_buffer.get_handle(), position, )) { - return Err(io::Error::last_os_error()); + Err(io::Error::last_os_error())?; } } Ok(()) } /// change the cursor visibility. - pub fn set_visibility(&self, visable: bool) -> io::Result<()> { + pub fn set_visibility(&self, visable: bool) -> Result<()> { let cursor_info = CONSOLE_CURSOR_INFO { dwSize: 100, bVisible: if visable { TRUE } else { FALSE }, @@ -90,14 +91,14 @@ impl Cursor { **self.screen_buffer.get_handle(), &cursor_info, )) { - return Err(io::Error::last_os_error()); + Err(io::Error::last_os_error())?; } } Ok(()) } /// Reset to saved cursor position - pub fn reset_to_saved_position() -> io::Result<()> { + pub fn reset_to_saved_position() -> Result<()> { let cursor = Cursor::new()?; unsafe { @@ -108,7 +109,7 @@ impl Cursor { } /// Save current cursor position to recall later. - pub fn save_cursor_pos() -> io::Result<()> { + pub fn save_cursor_pos() -> Result<()> { let cursor = Cursor::new()?; let position = cursor.position()?; diff --git a/crossterm_input/src/input.rs b/crossterm_input/src/input.rs index aa347f5eb..684cca913 100644 --- a/crossterm_input/src/input.rs +++ b/crossterm_input/src/input.rs @@ -1,8 +1,6 @@ //! 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; - #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -31,7 +29,7 @@ mod windows_input; /// Unix is using the 'TTY' and windows is using 'libc' C functions to read the input. trait ITerminalInput { /// Read one character from the user input - fn read_char(&self) -> io::Result; + fn read_char(&self) -> Result; /// Read the input asynchronously from the user. fn read_async(&self) -> AsyncReader; /// Read the input asynchronously until a certain character is hit. diff --git a/crossterm_input/src/input/input.rs b/crossterm_input/src/input/input.rs index 9fd59fc85..aa027c459 100644 --- a/crossterm_input/src/input/input.rs +++ b/crossterm_input/src/input/input.rs @@ -57,7 +57,7 @@ impl TerminalInput { /// Err(e) => println!("error: {}", e), /// } /// ``` - pub fn read_line(&self) -> io::Result { + pub fn read_line(&self) -> Result { let mut rv = String::new(); io::stdin().read_line(&mut rv)?; let len = rv.trim_end_matches(&['\r', '\n'][..]).len(); @@ -74,7 +74,7 @@ impl TerminalInput { /// Err(e) => println!("error: {}", e), /// } /// ``` - pub fn read_char(&self) -> io::Result { + pub fn read_char(&self) -> Result { self.input.read_char() } diff --git a/crossterm_input/src/input/unix_input.rs b/crossterm_input/src/input/unix_input.rs index 07186a2d9..b0d632ef8 100644 --- a/crossterm_input/src/input/unix_input.rs +++ b/crossterm_input/src/input/unix_input.rs @@ -26,7 +26,7 @@ impl UnixInput { } impl ITerminalInput for UnixInput { - fn read_char(&self) -> io::Result { + fn read_char(&self) -> Result { read_char_raw() } diff --git a/crossterm_input/src/input/windows_input.rs b/crossterm_input/src/input/windows_input.rs index 88a8744b2..f33742cdd 100644 --- a/crossterm_input/src/input/windows_input.rs +++ b/crossterm_input/src/input/windows_input.rs @@ -42,27 +42,23 @@ const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008; static mut ORIG_MODE: u32 = 0; impl ITerminalInput for WindowsInput { - fn read_char(&self) -> io::Result { + fn read_char(&self) -> Result { // _getwch is without echo and _getwche is with echo let pressed_char = unsafe { _getwche() }; // we could return error but maybe option to keep listening until valid character is inputted. if pressed_char == 0 || pressed_char == 0xe0 { - return Err(io::Error::new( + Err(io::Error::new( io::ErrorKind::Other, "Given input char is not a valid char, mostly occurs when pressing special keys", - )); + ))?; } - match char::from_u32(pressed_char as u32) { - Some(c) => { - return Ok(c); - } - None => Err(io::Error::new( - io::ErrorKind::Other, - "Could not parse given input to char", - )), - } + let ch = char::from_u32(pressed_char as u32).ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "Could not parse given input to char") + })?; + + Ok(ch) } fn read_async(&self) -> AsyncReader { diff --git a/crossterm_input/src/sys/unix.rs b/crossterm_input/src/sys/unix.rs index 22ab8108b..bae349b9b 100644 --- a/crossterm_input/src/sys/unix.rs +++ b/crossterm_input/src/sys/unix.rs @@ -1,17 +1,21 @@ use std::os::unix::io::AsRawFd; use std::{fs, io}; +use crossterm_utils::Result; + /// Get the TTY device. /// /// This allows for getting stdio representing _only_ the TTY, and not other streams. -pub fn get_tty() -> io::Result { - fs::OpenOptions::new() +pub fn get_tty() -> Result { + let file = fs::OpenOptions::new() .read(true) .write(true) - .open("/dev/tty") + .open("/dev/tty")?; + + Ok(file) } -fn get_tty_fd() -> io::Result { +fn get_tty_fd() -> Result { let fd = unsafe { if libc::isatty(libc::STDIN_FILENO) == 1 { libc::STDIN_FILENO @@ -23,7 +27,7 @@ fn get_tty_fd() -> io::Result { Ok(fd) } -pub fn read_char_raw() -> io::Result { +pub fn read_char_raw() -> Result { let mut buf = [0u8; 20]; let fd = get_tty_fd()?; @@ -50,7 +54,7 @@ pub fn read_char_raw() -> io::Result { pressed_char } - }; + }?; - rv + Ok(rv) } diff --git a/crossterm_screen/src/screen/alternate.rs b/crossterm_screen/src/screen/alternate.rs index 05968e174..b2aa6b7cc 100644 --- a/crossterm_screen/src/screen/alternate.rs +++ b/crossterm_screen/src/screen/alternate.rs @@ -5,10 +5,9 @@ //! For an example of this behavior, consider when vim is launched from bash. //! Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged. -use std::io; - #[cfg(windows)] use crossterm_utils::supports_ansi; +use crossterm_utils::Result; #[cfg(windows)] use crate::sys::winapi::ToAlternateScreenCommand; @@ -38,7 +37,7 @@ impl AlternateScreen { /// The alternate buffer dimensions are exactly the same as the window, without any scrollback region. /// For an example of this behavior, consider when vim is launched from bash. /// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged. - pub fn to_alternate(raw_mode: bool) -> io::Result { + pub fn to_alternate(raw_mode: bool) -> Result { #[cfg(windows)] let command = if supports_ansi() { Box::from(sys::ToAlternateScreenCommand::new()) @@ -68,9 +67,8 @@ impl AlternateScreen { } /// Switch the alternate screen back to the main screen. - pub fn to_main(&self) -> io::Result<()> { - self.command.disable()?; - Ok(()) + pub fn to_main(&self) -> Result<()> { + self.command.disable() } } diff --git a/crossterm_screen/src/screen/raw.rs b/crossterm_screen/src/screen/raw.rs index f72211651..9bae9d7ac 100644 --- a/crossterm_screen/src/screen/raw.rs +++ b/crossterm_screen/src/screen/raw.rs @@ -14,7 +14,9 @@ //! //! With these modes you can easier design the terminal screen. -use std::io::{self, Stdout, Write}; +use std::io::{Stdout, Write}; + +use crossterm_utils::Result; use crate::sys; @@ -27,7 +29,7 @@ pub struct RawScreen { impl RawScreen { /// Put terminal in raw mode. - pub fn into_raw_mode() -> io::Result { + pub fn into_raw_mode() -> Result { #[cfg(unix)] let mut command = sys::unix::RawModeCommand::new(); #[cfg(windows)] @@ -39,7 +41,7 @@ impl RawScreen { } /// Put terminal back in original modes. - pub fn disable_raw_mode() -> io::Result<()> { + pub fn disable_raw_mode() -> Result<()> { #[cfg(unix)] let mut command = sys::unix::RawModeCommand::new(); #[cfg(windows)] @@ -67,11 +69,11 @@ pub trait IntoRawMode: Write + Sized { /// Raw mode means that stdin won't be printed (it will instead have to be written manually by /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can /// read from stdin one byte of a time). The output is neither modified in any way. - fn into_raw_mode(self) -> io::Result; + fn into_raw_mode(self) -> Result; } impl IntoRawMode for Stdout { - fn into_raw_mode(self) -> io::Result { + fn into_raw_mode(self) -> Result { RawScreen::into_raw_mode()?; // this make's sure that raw screen will be disabled when it goes out of scope. Ok(RawScreen { drop: true }) diff --git a/crossterm_screen/src/sys/unix.rs b/crossterm_screen/src/sys/unix.rs index 046022cf3..1a93b924d 100644 --- a/crossterm_screen/src/sys/unix.rs +++ b/crossterm_screen/src/sys/unix.rs @@ -1,4 +1,4 @@ -use std::io::Result; +use crossterm_utils::Result; /// This command is used for enabling and disabling raw mode for the terminal. pub struct RawModeCommand; diff --git a/crossterm_screen/src/sys/winapi.rs b/crossterm_screen/src/sys/winapi.rs index 3f1679f86..58e19bd1a 100644 --- a/crossterm_screen/src/sys/winapi.rs +++ b/crossterm_screen/src/sys/winapi.rs @@ -1,5 +1,3 @@ -use std::io; - use winapi::shared::minwindef::DWORD; use winapi::um::wincon; @@ -27,7 +25,7 @@ impl RawModeCommand { impl RawModeCommand { /// Enables raw mode. - pub fn enable(&mut self) -> io::Result<()> { + pub fn enable(&mut self) -> Result<()> { let console_mode = ConsoleMode::new()?; let dw_mode = console_mode.mode()?; @@ -40,7 +38,7 @@ impl RawModeCommand { } /// Disables raw mode. - pub fn disable(&self) -> io::Result<()> { + pub fn disable(&self) -> Result<()> { let console_mode = ConsoleMode::new()?; let dw_mode = console_mode.mode()?; diff --git a/crossterm_style/src/color.rs b/crossterm_style/src/color.rs index e19c54f65..5dfff0316 100644 --- a/crossterm_style/src/color.rs +++ b/crossterm_style/src/color.rs @@ -3,7 +3,6 @@ use std::clone::Clone; use std::fmt::Display; -use std::io; #[cfg(windows)] use crossterm_utils::supports_ansi; @@ -67,7 +66,7 @@ impl TerminalColor { /// Get available color count. /// (This does not always provide a good result.) - pub fn get_available_color_count(&self) -> io::Result { + pub fn get_available_color_count(&self) -> Result { use std::env; Ok(match env::var_os("TERM") { Some(val) => { diff --git a/crossterm_style/src/winapi_color.rs b/crossterm_style/src/winapi_color.rs index 458b089a2..0a581b34d 100644 --- a/crossterm_style/src/winapi_color.rs +++ b/crossterm_style/src/winapi_color.rs @@ -1,7 +1,6 @@ //! This is a `WinApi` specific implementation for styling related action. //! This module is used for non supporting `ANSI` Windows terminals. -use std::io; use std::sync::Once; use winapi::um::wincon; @@ -173,7 +172,7 @@ fn color_value(color: Colored) -> String { winapi_color.to_string() } -fn init_console_color() -> io::Result<()> { +fn init_console_color() -> Result<()> { let screen_buffer = ScreenBuffer::current()?; let attr = screen_buffer.info()?.attributes(); diff --git a/crossterm_utils/src/command.rs b/crossterm_utils/src/command.rs index 72c473181..7590b87c7 100644 --- a/crossterm_utils/src/command.rs +++ b/crossterm_utils/src/command.rs @@ -1,8 +1,7 @@ use std::fmt::Display; use std::io::Write; -use crate::Result; -use crate::{execute, impl_display, queue, write_cout}; +use crate::{execute, impl_display, queue, write_cout, Result}; /// A command is an action that can be performed on the terminal. /// diff --git a/crossterm_utils/src/error.rs b/crossterm_utils/src/error.rs index 80a3f0e7f..7085decd1 100644 --- a/crossterm_utils/src/error.rs +++ b/crossterm_utils/src/error.rs @@ -49,18 +49,3 @@ impl From for ErrorKind { ErrorKind::FmtError(e) } } - -//impl From for ErrorKind { -// fn from(e: fmt::Error) -> ErrorKind { -// ErrorKind::FmtError(e) -// } -//} - -impl From for io::Error { - fn from(e: ErrorKind) -> io::Error { - match e { - ErrorKind::IoError(io) => return io, - _ => io::Error::new(io::ErrorKind::Other, "can not convert error to IO error"), - } - } -} diff --git a/crossterm_utils/src/sys/unix.rs b/crossterm_utils/src/sys/unix.rs index 26f7ea989..5f3f01e45 100644 --- a/crossterm_utils/src/sys/unix.rs +++ b/crossterm_utils/src/sys/unix.rs @@ -4,12 +4,14 @@ use std::{io, mem}; pub use libc::{c_int, termios as Termios}; +use crate::{ErrorKind, Result}; + static mut ORIGINAL_TERMINAL_MODE: Option = None; pub static mut RAW_MODE_ENABLED: bool = false; -fn unwrap(t: i32) -> io::Result<()> { +fn unwrap(t: i32) -> Result<()> { if t == -1 { - Err(io::Error::last_os_error()) + Err(ErrorKind::IoError(io::Error::last_os_error())) } else { Ok(()) } @@ -23,7 +25,7 @@ pub fn raw_terminal_attr(termios: &mut Termios) { unsafe { cfmakeraw(termios) } } -pub fn get_terminal_attr() -> io::Result { +pub fn get_terminal_attr() -> Result { extern "C" { pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int; } @@ -34,14 +36,14 @@ pub fn get_terminal_attr() -> io::Result { } } -pub fn set_terminal_attr(termios: &Termios) -> io::Result<()> { +pub fn set_terminal_attr(termios: &Termios) -> Result<()> { extern "C" { pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int; } unwrap(unsafe { tcsetattr(0, 0, termios) }).and(Ok(())) } -pub fn into_raw_mode() -> io::Result<()> { +pub fn into_raw_mode() -> Result<()> { let mut ios = get_terminal_attr()?; let prev_ios = ios; @@ -57,7 +59,7 @@ pub fn into_raw_mode() -> io::Result<()> { Ok(()) } -pub fn disable_raw_mode() -> io::Result<()> { +pub fn disable_raw_mode() -> Result<()> { unsafe { if ORIGINAL_TERMINAL_MODE.is_some() { set_terminal_attr(&ORIGINAL_TERMINAL_MODE.unwrap())?; diff --git a/crossterm_utils/src/sys/winapi.rs b/crossterm_utils/src/sys/winapi.rs index 313c2c85c..c6ed7a19c 100644 --- a/crossterm_utils/src/sys/winapi.rs +++ b/crossterm_utils/src/sys/winapi.rs @@ -1,8 +1,7 @@ pub mod ansi { - use std::io; - use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING; + use crate::Result; use crossterm_winapi::ConsoleMode; /// Toggle virtual terminal processing. @@ -14,7 +13,7 @@ pub mod ansi { /// When virtual terminal processing is enabled, characters emitted to the /// console are parsed for VT100 and similar control character sequences /// that control color and other similar operations. - pub fn set_virtual_terminal_processing(yes: bool) -> io::Result<()> { + pub fn set_virtual_terminal_processing(yes: bool) -> Result<()> { let mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING; let console_mode = ConsoleMode::new()?; diff --git a/examples/alternate_screen.rs b/examples/alternate_screen.rs index faf792788..f609e9f8a 100644 --- a/examples/alternate_screen.rs +++ b/examples/alternate_screen.rs @@ -1,8 +1,8 @@ -use std::{io, thread, time}; +use std::{thread, time}; -use crossterm::{style, AlternateScreen, ClearType, Color, Crossterm}; +use crossterm::{style, AlternateScreen, ClearType, Color, Crossterm, Result}; -fn print_wait_screen() -> io::Result<()> { +fn print_wait_screen() -> Result<()> { let crossterm = Crossterm::new(); let terminal = crossterm.terminal(); let cursor = crossterm.cursor(); @@ -34,15 +34,12 @@ fn print_wait_screen() -> io::Result<()> { } /// print wait screen on alternate screen, then switch back. -pub fn print_wait_screen_on_alternate_window() -> io::Result<()> { - if let Ok(_alternate) = AlternateScreen::to_alternate(false) { - print_wait_screen()?; - } - - Ok(()) +fn print_wait_screen_on_alternate_window() -> Result<()> { + let _alt = AlternateScreen::to_alternate(false)?; + print_wait_screen() } // cargo run --example alternate_screen -fn main() { - print_wait_screen_on_alternate_window().unwrap(); +fn main() -> Result<()> { + print_wait_screen_on_alternate_window() } diff --git a/examples/command.rs b/examples/command.rs index bcced8670..719066d79 100644 --- a/examples/command.rs +++ b/examples/command.rs @@ -29,9 +29,7 @@ fn execute_command_directly_using_macros() -> Result<()> { stdout(), Output("Text2 ".to_string()), Output("Text 3".to_string()) - )?; - - Ok(()) + ) } /// queue commands without executing them directly by using normal functions @@ -81,4 +79,9 @@ fn later_execution_command_directly_using_macros() -> Result<()> { } // cargo run --example command -fn main() {} +fn main() -> Result<()> { + later_execution_command_directly_using_macros() + // later_execution_command_using_functions() + // execute_command_directly_using_macros() + // execute_command_directly_using_functions() +} diff --git a/examples/command_bar.rs b/examples/command_bar.rs index 9847a2e1f..ac92878ab 100644 --- a/examples/command_bar.rs +++ b/examples/command_bar.rs @@ -2,14 +2,61 @@ use std::sync::{Arc, Mutex}; use std::{thread, time}; use crossterm::{ - cursor, input, terminal, ClearType, Crossterm, InputEvent, KeyEvent, RawScreen, Terminal, - TerminalCursor, + cursor, input, terminal, ClearType, Crossterm, InputEvent, KeyEvent, RawScreen, Result, + Terminal, TerminalCursor, }; +fn log(input_buf: Arc>) -> Vec> { + let mut threads = Vec::with_capacity(10); + + let (_, term_height) = terminal().terminal_size(); + + for i in 0..1 { + let input_buffer = input_buf.clone(); + + let crossterm = Crossterm::new(); + + let join = thread::spawn(move || { + let cursor = crossterm.cursor(); + let terminal = crossterm.terminal(); + + for j in 0..1000 { + if let Err(_) = swap_write( + format!("Some output: {} from thread: {}", j, i).as_ref(), + &input_buffer.lock().unwrap(), + &terminal, + &cursor, + term_height, + ) { + return; + } + thread::sleep(time::Duration::from_millis(100)); + } + }); + + threads.push(join); + } + + threads +} + +fn swap_write( + msg: &str, + input_buf: &String, + terminal: &Terminal, + cursor: &TerminalCursor, + term_height: u16, +) -> Result<()> { + cursor.goto(0, term_height)?; + terminal.clear(ClearType::CurrentLine)?; + terminal.write(format!("{}\r\n", msg))?; + terminal.write(format!("> {}", input_buf)).map(|_| ()) +} + // cargo run --example command_bar -fn main() { +fn main() -> Result<()> { let _screen = RawScreen::into_raw_mode(); - cursor().hide().expect("Couldn't hide cursor"); + cursor().hide()?; let input_buf = Arc::new(Mutex::new(String::new())); @@ -43,56 +90,5 @@ fn main() { thread.join().expect("Couldn't join"); } - cursor().show().expect("Couldn't show cursor"); -} - -fn log(input_buf: Arc>) -> Vec> { - let mut threads = Vec::with_capacity(10); - - let (_, term_height) = terminal().terminal_size(); - - for i in 0..1 { - let input_buffer = input_buf.clone(); - - let crossterm = Crossterm::new(); - - let join = thread::spawn(move || { - let cursor = crossterm.cursor(); - let terminal = crossterm.terminal(); - - for j in 0..1000 { - swap_write( - format!("Some output: {} from thread: {}", j, i).as_ref(), - &input_buffer.lock().unwrap(), - &terminal, - &cursor, - term_height, - ); - thread::sleep(time::Duration::from_millis(100)); - } - }); - - threads.push(join); - } - - return threads; -} - -pub fn swap_write( - msg: &str, - input_buf: &String, - terminal: &Terminal, - cursor: &TerminalCursor, - term_height: u16, -) { - cursor.goto(0, term_height).expect("Couldn't goto"); - terminal - .clear(ClearType::CurrentLine) - .expect("Couldn't clear current line"); - terminal - .write(format!("{}\r\n", msg)) - .expect("Couldn't write message"); - terminal - .write(format!("> {}", input_buf)) - .expect("Couldn't write prompt"); + cursor().show() } diff --git a/examples/cursor.rs b/examples/cursor.rs index fd3ac6d48..c4476ea41 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -2,12 +2,12 @@ //! Examples of actions that could be performed with the cursor. //! -use std::io; +#![allow(dead_code)] -use crossterm_cursor::cursor; +use crossterm::{cursor, Result}; /// Set the cursor to position X: 10, Y: 5 in the terminal. -pub fn goto() -> io::Result<()> { +fn goto() -> Result<()> { // Get the cursor let cursor = cursor(); // Set the cursor to position X: 10, Y: 5 in the terminal @@ -17,7 +17,7 @@ pub fn goto() -> io::Result<()> { } /// get the cursor position -pub fn pos() { +fn pos() { // Get the cursor let cursor = cursor(); // get the cursor position. @@ -27,7 +27,7 @@ pub fn pos() { } /// Move the cursor 3 up | demonstration. -pub fn move_up() { +fn move_up() { // Get the cursor let mut cursor = cursor(); @@ -36,21 +36,21 @@ pub fn move_up() { } /// Move the cursor 3 to the right | demonstration. -pub fn move_right() { +fn move_right() { let mut cursor = cursor(); // Move the cursor to position 3 times to the right in the terminal cursor.move_right(3); } /// Move the cursor 3 down | demonstration. -pub fn move_down() { +fn move_down() { let mut cursor = cursor(); // Move the cursor to position 3 times to the down in the terminal cursor.move_down(3); } /// Save and reset cursor position | demonstration.. -pub fn save_and_reset_position() -> io::Result<()> { +fn save_and_reset_position() -> Result<()> { let cursor = cursor(); // Goto X: 5 Y: 5 @@ -72,25 +72,30 @@ pub fn save_and_reset_position() -> io::Result<()> { } /// Hide cursor display | demonstration. -pub fn hide_cursor() { +fn hide_cursor() -> Result<()> { let cursor = cursor(); - cursor.hide().unwrap(); + cursor.hide() } /// Show cursor display | demonstration. -pub fn show_cursor() { +fn show_cursor() -> Result<()> { let cursor = cursor(); - cursor.show().unwrap(); + cursor.show() } /// Show cursor display, only works on certain terminals.| demonstration -pub fn blink_cursor() { +fn blink_cursor(enable: bool) -> Result<()> { let cursor = cursor(); - cursor.blink(false).unwrap(); - cursor.blink(false).unwrap(); + cursor.blink(enable) } // cargo run --example cursor -fn main() { - hide_cursor() +fn main() -> Result<()> { + println!("Going to show cursor..."); + show_cursor()?; + println!("Going to enable blinking cursor & sleep for 5s..."); + blink_cursor(true)?; + std::thread::sleep(std::time::Duration::from_secs(5)); + println!("Going to disable blinking cursor..."); + blink_cursor(false) } diff --git a/examples/input.rs b/examples/input.rs index 9d362c701..8de8e204f 100644 --- a/examples/input.rs +++ b/examples/input.rs @@ -1,6 +1,6 @@ use crossterm::input; -pub fn read_char() { +fn read_char() { let input = input(); match input.read_char() { @@ -9,7 +9,7 @@ pub fn read_char() { } } -pub fn read_line() { +fn read_line() { let input = input(); match input.read_line() { diff --git a/examples/key_events.rs b/examples/key_events.rs index 868d8f3c5..168249455 100644 --- a/examples/key_events.rs +++ b/examples/key_events.rs @@ -1,6 +1,8 @@ +#![allow(dead_code)] + use std::{thread, time::Duration}; -use crossterm::{input, InputEvent, KeyEvent, MouseButton, MouseEvent, RawScreen}; +use crossterm::{input, InputEvent, KeyEvent, MouseButton, MouseEvent, RawScreen, Result}; fn process_input_event(key_event: InputEvent) -> bool { match key_event { @@ -71,60 +73,60 @@ fn process_input_event(key_event: InputEvent) -> bool { _ => println!("Unknown!"), } - return false; + false } -pub fn read_asynchronously() { +fn read_asynchronously() -> Result<()> { // make sure to enable raw mode, this will make sure key events won't be handled by the terminal it's self and allows crossterm to read the input and pass it back to you. - if let Ok(_raw) = RawScreen::into_raw_mode() { - let input = input(); + let _raw = RawScreen::into_raw_mode()?; - // enable mouse events to be captured. - input.enable_mouse_mode().unwrap(); + let input = input(); - let mut stdin = input.read_async(); + // enable mouse events to be captured. + input.enable_mouse_mode()?; - loop { - if let Some(key_event) = stdin.next() { - if process_input_event(key_event) { - break; - } + let mut stdin = input.read_async(); + + loop { + if let Some(key_event) = stdin.next() { + if process_input_event(key_event) { + break; } - thread::sleep(Duration::from_millis(50)); } + thread::sleep(Duration::from_millis(50)); + } - // disable mouse events to be captured. - input.disable_mouse_mode().unwrap(); - } // <=== raw modes will be disabled here -} // <=== background reader will be disposed when dropped. + // disable mouse events to be captured. + input.disable_mouse_mode() +} // <=== raw modes will be disabled here -pub fn read_synchronously() { +fn read_synchronously() -> Result<()> { // make sure to enable raw mode, this will make sure key events won't be handled by the terminal it's self and allows crossterm to read the input and pass it back to you. - if let Ok(_raw) = RawScreen::into_raw_mode() { - let input = input(); + let _raw = RawScreen::into_raw_mode()?; - // enable mouse events to be captured. - input.enable_mouse_mode().unwrap(); + let input = input(); - let mut sync_stdin = input.read_sync(); + // enable mouse events to be captured. + input.enable_mouse_mode()?; - loop { - let event = sync_stdin.next(); + let mut sync_stdin = input.read_sync(); - if let Some(key_event) = event { - if process_input_event(key_event) { - break; - } + loop { + let event = sync_stdin.next(); + + if let Some(key_event) = event { + if process_input_event(key_event) { + break; } } + } - // disable mouse events to be captured. - input.disable_mouse_mode().unwrap(); - } // <=== raw modes will be disabled here -} + // disable mouse events to be captured. + input.disable_mouse_mode() +} // <=== raw modes will be disabled here // cargo run --example key_events -fn main() { - // read_synchronously(); - // read_asynchronously(); +fn main() -> Result<()> { + read_synchronously() + // read_asynchronously() } diff --git a/examples/raw_mode.rs b/examples/raw_mode.rs index 7128c89cc..e9f4d4249 100644 --- a/examples/raw_mode.rs +++ b/examples/raw_mode.rs @@ -1,9 +1,9 @@ -use std::io::{self, stdout, Write}; +use std::io::{stdout, Write}; use std::{thread, time}; -use crossterm::{style, AlternateScreen, ClearType, Color, Crossterm}; +use crossterm::{style, AlternateScreen, ClearType, Color, Crossterm, Result}; -fn print_wait_screen() -> io::Result<()> { +fn print_wait_screen() -> Result<()> { let crossterm = Crossterm::new(); let terminal = crossterm.terminal(); let cursor = crossterm.cursor(); @@ -39,16 +39,13 @@ fn print_wait_screen() -> io::Result<()> { Ok(()) } -pub fn print_wait_screen_on_alternate_window() -> io::Result<()> { +fn print_wait_screen_on_alternate_window() -> Result<()> { // by passing in 'true' the alternate screen will be in raw modes. - if let Ok(_alternate) = AlternateScreen::to_alternate(true) { - print_wait_screen()?; - } // <- drop alternate screen; this will cause the alternate screen to drop. - - Ok(()) + let _alt = AlternateScreen::to_alternate(true)?; + print_wait_screen() } // cargo run --example raw_mode -fn main() { - print_wait_screen_on_alternate_window().unwrap(); +fn main() -> Result<()> { + print_wait_screen_on_alternate_window() } diff --git a/examples/style.rs b/examples/style.rs index a3ee9fef6..6450d20f1 100644 --- a/examples/style.rs +++ b/examples/style.rs @@ -1,22 +1,25 @@ //! //! Examples of coloring the terminal. //! + +#![allow(dead_code)] + use crossterm::{color, Attribute, Color, Colored, Colorize, Styler}; /// print some red text | demonstration. -pub fn paint_foreground() { +fn paint_foreground() { println!("{}", "Red foreground text: {}".red()); println!("{} Red foreground text", Colored::Fg(Color::Red)); } /// print some text on red background | demonstration. -pub fn paint_background() { +fn paint_background() { println!("{}", "Red background text: {}".on_red()); println!("{} Red background text", Colored::Bg(Color::Red)); } /// Print all available foreground colors | demonstration. -pub fn print_all_foreground_colors_with_enum() { +fn print_all_foreground_colors_with_enum() { // we use `Reset` to restore the foreground back to normal at the end of the line. println!( "Black : \t\t {} ■ {}\n", @@ -114,7 +117,7 @@ pub fn print_all_foreground_colors_with_enum() { } /// Print all available foreground colors | demonstration. -pub fn print_all_foreground_colors_with_method() { +fn print_all_foreground_colors_with_method() { println!( "Black : \t\t {} {}\n", "■".black(), @@ -182,7 +185,7 @@ pub fn print_all_foreground_colors_with_method() { } /// Print all available foreground colors | demonstration. -pub fn print_all_background_colors_with_enum() { +fn print_all_background_colors_with_enum() { println!( "Black : \t\t {} ■ {}\n", Colored::Bg(Color::Black), @@ -279,7 +282,7 @@ pub fn print_all_background_colors_with_enum() { } /// Print all available foreground colors | demonstration. -pub fn print_all_background_colors_with_method() { +fn print_all_background_colors_with_method() { println!( "Black : \t\t {} {}\n", "■".on_black(), @@ -364,7 +367,7 @@ pub fn print_all_background_colors_with_method() { /// Print text with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration.. #[cfg(unix)] -pub fn print_text_with_attributes() { +fn print_text_with_attributes() { println!("{}", "Normal text"); println!("{}", "Bold text".bold()); println!("{}", "Italic text".italic()); @@ -387,7 +390,7 @@ pub fn print_text_with_attributes() { // Print text with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration.. #[cfg(windows)] -pub fn print_text_with_attributes() { +fn print_text_with_attributes() { println!("{}", "Normal text"); println!("{}", "Bold text".bold()); println!("{}", "Underlined text".underlined()); @@ -395,7 +398,7 @@ pub fn print_text_with_attributes() { } /// Print all supported RGB colors, not supported for Windows systems < 10 | demonstration. -pub fn print_supported_colors() { +fn print_supported_colors() { let count = color().get_available_color_count().unwrap(); for i in 0..count { @@ -403,7 +406,7 @@ pub fn print_supported_colors() { } } -pub fn reset_fg_and_bg() { +fn reset_fg_and_bg() { println!("{}", Colored::Fg(Color::Reset)); println!("{}", Colored::Bg(Color::Reset)); } diff --git a/examples/terminal.rs b/examples/terminal.rs index b5acd97ce..eff54f452 100644 --- a/examples/terminal.rs +++ b/examples/terminal.rs @@ -2,9 +2,9 @@ //! Terminal Examples //! -use std::io; +#![allow(dead_code)] -use crossterm::{cursor, terminal, ClearType}; +use crossterm::{cursor, terminal, ClearType, Result}; fn print_test_data() { for i in 0..100 { @@ -13,19 +13,17 @@ fn print_test_data() { } /// Clear all lines in terminal | demonstration -pub fn clear_all_lines() -> io::Result<()> { +fn clear_all_lines() -> Result<()> { let terminal = terminal(); print_test_data(); // Clear all lines in terminal; - terminal.clear(ClearType::All)?; - - Ok(()) + terminal.clear(ClearType::All) } /// Clear all lines from cursor position X:4, Y:4 down | demonstration -pub fn clear_from_cursor_down() -> io::Result<()> { +fn clear_from_cursor_down() -> Result<()> { let terminal = terminal(); print_test_data(); @@ -34,13 +32,11 @@ pub fn clear_from_cursor_down() -> io::Result<()> { cursor().goto(4, 8)?; // Clear all cells from current cursor position down. - terminal.clear(ClearType::FromCursorDown)?; - - Ok(()) + terminal.clear(ClearType::FromCursorDown) } /// Clear all lines from cursor position X:4, Y:4 up | demonstration -pub fn clear_from_cursor_up() -> io::Result<()> { +fn clear_from_cursor_up() -> Result<()> { let terminal = terminal(); print_test_data(); @@ -49,13 +45,11 @@ pub fn clear_from_cursor_up() -> io::Result<()> { cursor().goto(4, 4)?; // Clear all cells from current cursor position down. - terminal.clear(ClearType::FromCursorUp)?; - - Ok(()) + terminal.clear(ClearType::FromCursorUp) } /// Clear all lines from cursor position X:4, Y:4 up | demonstration -pub fn clear_current_line() -> io::Result<()> { +fn clear_current_line() -> Result<()> { let terminal = terminal(); print_test_data(); @@ -64,13 +58,11 @@ pub fn clear_current_line() -> io::Result<()> { cursor().goto(4, 3)?; // Clear current line cells. - terminal.clear(ClearType::CurrentLine)?; - - Ok(()) + terminal.clear(ClearType::CurrentLine) } /// Clear all lines from cursor position X:4, Y:7 up | demonstration -pub fn clear_until_new_line() -> io::Result<()> { +fn clear_until_new_line() -> Result<()> { let terminal = terminal(); print_test_data(); @@ -79,13 +71,11 @@ pub fn clear_until_new_line() -> io::Result<()> { cursor().goto(4, 20)?; // Clear all the cells until next line. - terminal.clear(ClearType::UntilNewLine)?; - - Ok(()) + terminal.clear(ClearType::UntilNewLine) } /// Print the the current terminal size | demonstration. -pub fn print_terminal_size() { +fn print_terminal_size() { let terminal = terminal(); // Get terminal size @@ -96,47 +86,39 @@ pub fn print_terminal_size() { } /// Set the terminal size to width 10, height: 10 | demonstration. -pub fn set_terminal_size() -> io::Result<()> { +fn set_terminal_size() -> Result<()> { let terminal = terminal(); - terminal.set_size(10, 10)?; - - Ok(()) + terminal.set_size(10, 10) } /// Scroll down 10 lines | demonstration. -pub fn scroll_down() -> io::Result<()> { +fn scroll_down() -> Result<()> { let terminal = terminal(); print_test_data(); // Scroll down 10 lines. - terminal.scroll_down(10)?; - - Ok(()) + terminal.scroll_down(10) } /// Scroll down 10 lines | demonstration. -pub fn scroll_up() -> io::Result<()> { +fn scroll_up() -> Result<()> { let terminal = terminal(); print_test_data(); // Scroll up 10 lines. - terminal.scroll_up(5)?; - - Ok(()) + terminal.scroll_up(10) } /// exit the current proccess. -pub fn exit() { +fn exit() { let terminal = terminal(); terminal.exit(); } // cargo run --example terminal -fn main() -> io::Result<()> { - scroll_down()?; - - Ok(()) +fn main() -> Result<()> { + scroll_down() }