aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-11-11 05:00:49 -0500
committerJesse Luehrs <doy@tozt.net>2019-11-11 05:00:49 -0500
commitc61c85a7985358d726cc0ba0649ce9b269b62d5c (patch)
treee26d6e4964e2845fbadc7381ecf4a1f5d2e18ce7
parent805f9348bfdbfea6cc48e2f03946ec84de4a3c53 (diff)
downloadvt100-rust-c61c85a7985358d726cc0ba0649ce9b269b62d5c.tar.gz
vt100-rust-c61c85a7985358d726cc0ba0649ce9b269b62d5c.zip
stop using formats at all
they are too slow
-rw-r--r--Cargo.toml1
-rw-r--r--src/attrs.rs7
-rw-r--r--src/grid.rs20
-rw-r--r--src/row.rs70
-rw-r--r--src/screen.rs17
-rw-r--r--src/term.rs91
6 files changed, 80 insertions, 126 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 1b955ed..1d2e329 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,7 @@ categories = ["command-line-interface", "encoding"]
license = "MIT"
[dependencies]
+itoa = "0.4"
enumset = "0.4"
log = "0.4"
unicode-normalization = "0.1"
diff --git a/src/attrs.rs b/src/attrs.rs
index 8ba4e7c..08ec857 100644
--- a/src/attrs.rs
+++ b/src/attrs.rs
@@ -1,4 +1,4 @@
-use std::io::Write as _;
+use crate::term::BufWrite as _;
/// Represents a foreground or background color for cells.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
@@ -95,8 +95,7 @@ impl Attrs {
other: &Self,
) {
if self != other && self == &Self::default() {
- write!(contents, "{}", crate::term::ClearAttrs::default())
- .unwrap();
+ crate::term::ClearAttrs::default().write_buf(contents);
return;
}
@@ -133,6 +132,6 @@ impl Attrs {
attrs.inverse(self.inverse())
};
- write!(contents, "{}", attrs).unwrap();
+ attrs.write_buf(contents);
}
}
diff --git a/src/grid.rs b/src/grid.rs
index 2d515ac..242a152 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -1,6 +1,5 @@
+use crate::term::BufWrite as _;
use std::convert::TryInto as _;
-use std::fmt::Write as _;
-use std::io::Write as _;
#[derive(Clone, Debug)]
pub struct Grid {
@@ -170,7 +169,7 @@ impl Grid {
for row in self.visible_rows() {
row.write_contents(contents, 0, self.size.cols);
if !row.wrapped() {
- writeln!(contents).unwrap();
+ contents.push_str("\n");
}
}
@@ -183,13 +182,8 @@ impl Grid {
&self,
contents: &mut Vec<u8>,
) -> crate::attrs::Attrs {
- write!(
- contents,
- "{}{}",
- crate::term::ClearAttrs::default(),
- crate::term::ClearScreen::default()
- )
- .unwrap();
+ crate::term::ClearAttrs::default().write_buf(contents);
+ crate::term::ClearScreen::default().write_buf(contents);
let mut prev_attrs = crate::attrs::Attrs::default();
let mut prev_pos = Pos::default();
@@ -211,8 +205,7 @@ impl Grid {
}
if prev_pos != self.pos {
- write!(contents, "{}", crate::term::MoveTo::new(self.pos))
- .unwrap();
+ crate::term::MoveTo::new(self.pos).write_buf(contents);
}
prev_attrs
@@ -246,8 +239,7 @@ impl Grid {
}
if prev_pos != self.pos {
- write!(contents, "{}", crate::term::MoveTo::new(self.pos))
- .unwrap();
+ crate::term::MoveTo::new(self.pos).write_buf(contents);
}
prev_attrs
diff --git a/src/row.rs b/src/row.rs
index ff855eb..26e117b 100644
--- a/src/row.rs
+++ b/src/row.rs
@@ -1,5 +1,5 @@
+use crate::term::BufWrite as _;
use std::convert::TryInto as _;
-use std::io::Write as _;
#[derive(Clone, Debug)]
pub struct Row {
@@ -87,8 +87,6 @@ impl Row {
}
if cell.has_contents() {
- // using write! here is significantly slower, for some reason
- // write!(contents, "{}", cell.contents()).unwrap();
contents.push_str(&cell.contents());
} else {
contents.push(' ');
@@ -135,26 +133,15 @@ impl Row {
|| prev_pos.col != self.cols()
|| pos.col != 0
{
- write!(
- contents,
- "{}{}",
- crate::term::CRLF::default(),
- crate::term::MoveRight::new(pos.col)
- )
- .unwrap();
+ crate::term::CRLF::default().write_buf(contents);
+ crate::term::MoveRight::new(pos.col)
+ .write_buf(contents);
}
} else if prev_pos.row == pos.row {
- write!(
- contents,
- "{}",
- crate::term::MoveRight::new(
- pos.col - prev_pos.col
- )
- )
- .unwrap();
+ crate::term::MoveRight::new(pos.col - prev_pos.col)
+ .write_buf(contents);
} else {
- write!(contents, "{}", crate::term::MoveTo::new(pos))
- .unwrap();
+ crate::term::MoveTo::new(pos).write_buf(contents);
}
prev_pos = pos;
}
@@ -167,9 +154,6 @@ impl Row {
prev_attrs = *attrs;
}
- // using write! here is significantly slower, for some
- // reason
- // write!(contents, "{}", cell.contents()).unwrap();
contents.extend(cell.contents().as_bytes());
prev_pos.col += if cell.is_wide() { 2 } else { 1 };
} else {
@@ -178,12 +162,7 @@ impl Row {
prev_attrs = *attrs;
}
- write!(
- contents,
- "{}",
- crate::term::EraseChar::default(),
- )
- .unwrap();
+ crate::term::EraseChar::default().write_buf(contents);
}
}
}
@@ -228,28 +207,17 @@ impl Row {
|| prev_pos.col != self.cols()
|| pos.col != 0
{
- write!(
- contents,
- "{}{}",
- crate::term::CRLF::default(),
- crate::term::MoveRight::new(pos.col)
- )
- .unwrap();
+ crate::term::CRLF::default().write_buf(contents);
+ crate::term::MoveRight::new(pos.col)
+ .write_buf(contents);
}
} else if prev_pos.row == pos.row
&& prev_pos.col < pos.col
{
- write!(
- contents,
- "{}",
- crate::term::MoveRight::new(
- pos.col - prev_pos.col
- )
- )
- .unwrap();
+ crate::term::MoveRight::new(pos.col - prev_pos.col)
+ .write_buf(contents);
} else {
- write!(contents, "{}", crate::term::MoveTo::new(pos))
- .unwrap();
+ crate::term::MoveTo::new(pos).write_buf(contents);
}
prev_pos = pos;
}
@@ -262,9 +230,6 @@ impl Row {
prev_attrs = *attrs;
}
- // using write! here is significantly slower, for some
- // reason
- // write!(contents, "{}", cell.contents()).unwrap();
contents.extend(cell.contents().as_bytes());
prev_pos.col += if cell.is_wide() { 2 } else { 1 };
} else {
@@ -273,12 +238,7 @@ impl Row {
prev_attrs = *attrs;
}
- write!(
- contents,
- "{}",
- crate::term::EraseChar::default(),
- )
- .unwrap();
+ crate::term::EraseChar::default().write_buf(contents);
}
}
}
diff --git a/src/screen.rs b/src/screen.rs
index 57b37fb..ce86312 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -1,5 +1,5 @@
+use crate::term::BufWrite as _;
use std::convert::TryInto as _;
-use std::io::Write as _;
use unicode_width::UnicodeWidthChar as _;
const DEFAULT_MULTI_PARAMS: &[i64] = &[0];
@@ -198,12 +198,7 @@ impl Screen {
}
fn write_contents_formatted(&self, contents: &mut Vec<u8>) {
- write!(
- contents,
- "{}",
- crate::term::HideCursor::new(self.hide_cursor())
- )
- .unwrap();
+ crate::term::HideCursor::new(self.hide_cursor()).write_buf(contents);
let prev_attrs = self.grid().write_contents_formatted(contents);
self.attrs.write_escape_code_diff(contents, &prev_attrs);
}
@@ -256,12 +251,8 @@ impl Screen {
fn write_contents_diff(&self, contents: &mut Vec<u8>, prev: &Self) {
if self.hide_cursor() != prev.hide_cursor() {
- write!(
- contents,
- "{}",
- crate::term::HideCursor::new(self.hide_cursor())
- )
- .unwrap();
+ crate::term::HideCursor::new(self.hide_cursor())
+ .write_buf(contents);
}
let prev_attrs = self.grid().write_contents_diff(
contents,
diff --git a/src/term.rs b/src/term.rs
index 54dfa1d..d353d35 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -1,20 +1,24 @@
// TODO: read all of this from terminfo
+pub trait BufWrite {
+ fn write_buf(&self, buf: &mut Vec<u8>);
+}
+
#[derive(Default, Debug)]
pub struct ClearScreen;
-impl std::fmt::Display for ClearScreen {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_str("\x1b[H\x1b[J")
+impl BufWrite for ClearScreen {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
+ buf.extend_from_slice(b"\x1b[H\x1b[J");
}
}
#[derive(Default, Debug)]
pub struct CRLF;
-impl std::fmt::Display for CRLF {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_str("\r\n")
+impl BufWrite for CRLF {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
+ buf.extend_from_slice(b"\r\n");
}
}
@@ -33,12 +37,16 @@ impl MoveTo {
}
}
-impl std::fmt::Display for MoveTo {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl BufWrite for MoveTo {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
if self.row == 0 && self.col == 0 {
- f.write_str("\x1b[H")
+ buf.extend_from_slice(b"\x1b[H");
} else {
- write!(f, "\x1b[{};{}H", self.row + 1, self.col + 1)
+ buf.extend_from_slice(b"\x1b[");
+ itoa::write(&mut *buf, self.row + 1).unwrap();
+ buf.push(b';');
+ itoa::write(&mut *buf, self.col + 1).unwrap();
+ buf.push(b'H');
}
}
}
@@ -46,9 +54,9 @@ impl std::fmt::Display for MoveTo {
#[derive(Default, Debug)]
pub struct ClearAttrs;
-impl std::fmt::Display for ClearAttrs {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_str("\x1b[m")
+impl BufWrite for ClearAttrs {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
+ buf.extend_from_slice(b"\x1b[m")
}
}
@@ -94,13 +102,9 @@ impl Attrs {
}
}
-impl std::fmt::Display for Attrs {
- #[allow(
- unused_assignments,
- clippy::cognitive_complexity,
- clippy::too_many_lines
- )]
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl BufWrite for Attrs {
+ #[allow(unused_assignments, clippy::cognitive_complexity)]
+ fn write_buf(&self, buf: &mut Vec<u8>) {
if self.fgcolor.is_none()
&& self.bgcolor.is_none()
&& self.bold.is_none()
@@ -108,10 +112,10 @@ impl std::fmt::Display for Attrs {
&& self.underline.is_none()
&& self.inverse.is_none()
{
- return Ok(());
+ return;
}
- f.write_str("\x1b[")?;
+ buf.extend_from_slice(b"\x1b[");
let mut first = true;
macro_rules! write_param {
@@ -119,9 +123,9 @@ impl std::fmt::Display for Attrs {
if first {
first = false;
} else {
- f.write_str(";")?;
+ buf.push(b';');
}
- write!(f, "{}", $i)?;
+ itoa::write(&mut *buf, $i).unwrap();
};
}
@@ -209,8 +213,7 @@ impl std::fmt::Display for Attrs {
}
}
- f.write_str("m")?;
- Ok(())
+ buf.push(b'm');
}
}
@@ -231,12 +234,16 @@ impl Default for MoveRight {
}
}
-impl std::fmt::Display for MoveRight {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl BufWrite for MoveRight {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
match self.count {
- 0 => Ok(()),
- 1 => f.write_str("\x1b[C"),
- n => write!(f, "\x1b[{}C", n),
+ 0 => {}
+ 1 => buf.extend_from_slice(b"\x1b[C"),
+ n => {
+ buf.extend_from_slice(b"\x1b[");
+ itoa::write(&mut *buf, n).unwrap();
+ buf.push(b'C');
+ }
}
}
}
@@ -252,12 +259,16 @@ impl Default for EraseChar {
}
}
-impl std::fmt::Display for EraseChar {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl BufWrite for EraseChar {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
match self.count {
- 0 => Ok(()),
- 1 => f.write_str("\x1b[X"),
- n => write!(f, "\x1b[{}X", n),
+ 0 => {}
+ 1 => buf.extend_from_slice(b"\x1b[X"),
+ n => {
+ buf.extend_from_slice(b"\x1b[");
+ itoa::write(&mut *buf, n).unwrap();
+ buf.push(b'X');
+ }
}
}
}
@@ -273,12 +284,12 @@ impl HideCursor {
}
}
-impl std::fmt::Display for HideCursor {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl BufWrite for HideCursor {
+ fn write_buf(&self, buf: &mut Vec<u8>) {
if self.hide {
- f.write_str("\x1b[?25l")
+ buf.extend_from_slice(b"\x1b[?25l")
} else {
- f.write_str("\x1b[?25h")
+ buf.extend_from_slice(b"\x1b[?25h")
}
}
}