Return written bytes (#212)

* `write_cout!` returns number of written bytes
* `Terminal::write` returns number of written bytes (result of `write_cout!`)
* `execute!` macro is a bit simpler
* Remove unused `std::io::Write` imports
This commit is contained in:
Zrzka 2019-09-14 16:42:42 +02:00 committed by Timon
parent 6c320b1c16
commit be05974b70
13 changed files with 49 additions and 66 deletions

View File

@ -1,11 +1,17 @@
//!
//! Examples of actions that could be performed with the cursor.
//!
#![allow(unused_must_use, dead_code)]
extern crate crossterm_cursor;
use std::io::Write;
use std::time::Instant;
use crossterm_cursor::cursor;
use self::crossterm_cursor::{queue, Goto, Hide, Output, QueueableCommand};
/// Set the cursor to position X: 10, Y: 5 in the terminal.
pub fn goto() {
// Get the cursor
@ -86,20 +92,11 @@ pub fn blink_cursor() {
cursor.blink(false);
}
use self::crossterm_cursor::{
execute, queue, BlinkOff, BlinkOn, Command, Down, ExecutableCommand, Goto, Hide, Left, Output,
QueueableCommand, ResetPos, Right, SavePos, Show, Up,
};
use std::fmt::Display;
use std::io::{stdout, Write};
use std::thread;
use std::time::{Duration, Instant};
fn benchmark_cursor_goto() -> f32 {
let mut stdout = ::std::io::stdout();
let instant1 = Instant::now();
for i in 0..10 {
for _ in 0..10 {
for x in 0..200 {
for y in 0..50 {
queue!(stdout, Goto(x, y), Hide, Output(y.to_string()));
@ -110,7 +107,7 @@ fn benchmark_cursor_goto() -> f32 {
let new_api = instant1.elapsed();
let cursor = cursor();
let instant2 = Instant::now();
for i in 0..10 {
for _ in 0..10 {
for x in 0..200 {
for y in 0..50 {
cursor.goto(x, y);
@ -128,10 +125,8 @@ fn benchmark_cursor_goto() -> f32 {
}
fn start_goto_benchmark() {
let mut stdout = ::std::io::stdout();
let mut performance_metrics = Vec::new();
for i in 1..=20 {
for _ in 1..=20 {
performance_metrics.push(benchmark_cursor_goto());
}
@ -142,7 +137,7 @@ fn start_goto_benchmark() {
}
fn main() {
let mut stdout = ::std::io::stdout();
let stdout = ::std::io::stdout();
stdout
.queue(Goto(5, 5))

View File

@ -4,7 +4,6 @@
use super::ITerminalCursor;
use crate::sys::{get_cursor_position, show_cursor};
use std::io::Write;
use crossterm_utils::{write_cout, Result};

View File

@ -1,3 +1,4 @@
#![allow(unused_must_use)]
use super::AnsiCursor;
use super::ITerminalCursor;

View File

@ -1,16 +1,16 @@
//! This is a UNIX specific implementation for input related action.
use super::*;
use crate::sys::unix::{get_tty, read_char_raw};
use crossterm_utils::{csi, write_cout, ErrorKind, Result};
use std::char;
use std::sync::atomic::{AtomicBool, Ordering};
use std::{
io::{Read, Write},
str,
};
use std::{io::Read, str};
use std::{sync::mpsc, thread};
use crossterm_utils::{csi, write_cout, ErrorKind, Result};
use crate::sys::unix::{get_tty, read_char_raw};
use super::*;
pub struct UnixInput;
impl UnixInput {

View File

@ -1,5 +1,3 @@
use std::io::Write;
use crossterm_utils::{csi, write_cout, Result};
#[cfg(unix)]

View File

@ -1,11 +1,10 @@
//! This is a ANSI specific implementation for styling related action.
//! This module is used for Windows 10 terminals and Unix terminals by default.
use std::io::Write;
use crossterm_utils::{csi, write_cout, Result};
use crate::{Attribute, Color, Colored, ITerminalColor};
use crate::Colored;
use crate::{Attribute, Color, ITerminalColor};
#[inline]
pub fn get_set_fg_ansi(fg_color: Color) -> String {

View File

@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize};
/// # Example
/// You can use an attribute in a write statement to apply the attribute to the terminal output.
///
/// ```rust
/// ```ignore
/// println!(
/// "{} Underlined {} No Underline",
/// Attribute::Underlined,
@ -25,8 +25,8 @@ use serde::{Deserialize, Serialize};
/// ```
///
/// You can also call attribute functions on a `&'static str`:
/// ```rust
/// use crossterm(_style)::Colorizer;
/// ```ignore
/// use Colorizer;
///
/// println!("{}", style("Bold text").bold());
/// println!("{}", style("Underlined text").underlined());

View File

@ -15,14 +15,13 @@ use crate::enums::Color;
///
/// You can use `Colored` in a write statement to apply the attribute to the terminal output.
///
/// ```rust
/// ```ignore
/// println!("{} Red foreground color", Colored::Fg(Color::Red));
/// println!("{} Blue background color", Colored::Bg(Color::Blue));
/// ```
///
/// You can also call coloring functions on a `&'static str`:
/// ```rust
/// use crossterm(_style)::Colorizer;
/// ```ignore
/// let styled_text = "Red forground color on blue background.".red().on_blue();
/// println!("{}", styled_text);
/// ```

View File

@ -46,7 +46,7 @@ trait ITerminalColor {
/// This could be used to style a type that implements `Display` with colors and attributes.
///
/// # Example
/// ```rust
/// ```ignore
/// // get a styled object which could be painted to the terminal.
/// let styled_object = style("Some Blue colored text on black background")
/// .with(Color::Blue)

View File

@ -6,7 +6,7 @@ use crate::StyledObject;
///
/// This trait is implemented for `&static str` and `StyledObject` and thus the methods of this trait could be called on them.
///
/// ``` rust
/// ```ignore
/// use Colorizer;
///
/// let styled_text = "Red forground color on blue background.".red().on_blue();
@ -53,7 +53,7 @@ pub trait Colorize<D: Display + Clone> {
/// This trait is implemented for `&static str` and `StyledObject` and thus the methods of this trait could be called on them.
///
/// # Example
/// ``` rust
/// ```ignore
/// use Colorizer;
///
/// println!("{}", "Bold text".bold();

View File

@ -1,8 +1,6 @@
//! This is an `ANSI escape code` specific implementation for terminal related action.
//! This module is used for windows 10 terminals and unix terminals by default.
use std::io::Write;
use crossterm_cursor::TerminalCursor;
use crossterm_utils::{csi, write_cout, Result};

View File

@ -2,7 +2,6 @@
//! Like clearing and scrolling in the terminal or getting the window size from the terminal.
use std::fmt;
use std::io::Write;
#[cfg(windows)]
use crossterm_utils::supports_ansi;
@ -131,8 +130,7 @@ impl Terminal {
///
/// This will also flush the standard output.
pub fn write<D: fmt::Display>(&self, value: D) -> Result<usize> {
write_cout!(format!("{}", value))?;
Ok(0)
write_cout!(format!("{}", value))
}
}

View File

@ -10,16 +10,19 @@ macro_rules! write_cout {
($write:expr, $string:expr) => {{
use $crate::ErrorKind;
if let Err(e) = write!($write, "{}", $string) {
Err(ErrorKind::IoError(e))
} else {
match $write.flush() {
Ok(size) => Ok(size),
Err(e) => Err(ErrorKind::IoError(e)),
}
}
let fmt = format!("{}", $string);
let bytes = fmt.as_bytes();
$write
.write_all(bytes)
.and_then(|_| $write.flush().map(|_| bytes.len()))
.map_err(ErrorKind::IoError)
}};
($string:expr) => {{
// Bring Write into the scope and ignore unused imports if it's
// already imported by the user
#[allow(unused_imports)]
use std::io::Write;
write_cout!(::std::io::stdout(), $string)
}};
}
@ -151,32 +154,25 @@ macro_rules! execute {
#[cfg(windows)]
{
if $crate::supports_ansi() {
match write_cout!($write, $command.get_ansi_code()) {
Err(e) => {
error = Some(Err($crate::ErrorKind::from(e)));
}
_ => {}
if let Err(e) = write_cout!($write, $command.get_ansi_code()) {
error = Some($crate::ErrorKind::from(e));
};
} else {
match $command.execute_winapi() {
Err(e) => {
error = Some(Err($crate::ErrorKind::from(e)));
}
_ => {}
if let Err(e) = $command.execute_winapi() {
error = Some($crate::ErrorKind::from(e));
};
};
}
#[cfg(unix)]
match write_cout!($write, $command.get_ansi_code()) {
Err(e) => {
error = Some(Err($crate::ErrorKind::from(e)));
{
if let Err(e) = write_cout!($write, $command.get_ansi_code()) {
error = Some($crate::ErrorKind::from(e));
}
}
_ => {}
};
)*
if let Some(error) = error {
error
Err(error)
} else {
Ok(())
}