Merge branch 'extra-derives' into 'master'
Extra derives & performance optimizations See merge request redox-os/termion!149
This commit is contained in:
commit
c25f4f3d30
|
@ -7,19 +7,19 @@ before_script:
|
||||||
stable:
|
stable:
|
||||||
script:
|
script:
|
||||||
- cargo +stable build --verbose
|
- cargo +stable build --verbose
|
||||||
- cargo +stable test --verbose
|
- script -q -c "cargo +stable test --verbose"
|
||||||
- cargo +stable test --release --verbose
|
- script -q -c "cargo +stable test --release --verbose"
|
||||||
|
|
||||||
beta:
|
beta:
|
||||||
script:
|
script:
|
||||||
- rustup toolchain add beta
|
- rustup toolchain add beta
|
||||||
- cargo +beta build --verbose
|
- cargo +beta build --verbose
|
||||||
- cargo +beta test --verbose
|
- script -q -c "cargo +beta test --verbose"
|
||||||
- cargo +beta test --release --verbose
|
- script -q -c "cargo +beta test --release --verbose"
|
||||||
|
|
||||||
nightly:
|
nightly:
|
||||||
script:
|
script:
|
||||||
- rustup toolchain add nightly
|
- rustup toolchain add nightly
|
||||||
- cargo +nightly build --verbose
|
- cargo +nightly build --verbose
|
||||||
- cargo +nightly test --verbose
|
- script -q -c "cargo +nightly test --verbose"
|
||||||
- cargo +nightly test --release --verbose
|
- script -q -c "cargo +nightly test --release --verbose"
|
||||||
|
|
|
@ -9,6 +9,9 @@ license = "MIT"
|
||||||
keywords = ["tty", "color", "terminal", "password", "tui"]
|
keywords = ["tty", "color", "terminal", "password", "tui"]
|
||||||
exclude = ["target", "CHANGELOG.md", "image.png", "Cargo.lock"]
|
exclude = ["target", "CHANGELOG.md", "image.png", "Cargo.lock"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
numtoa = { version = "0.1.0", features = ["std"]}
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "redox"))'.dependencies]
|
[target.'cfg(not(target_os = "redox"))'.dependencies]
|
||||||
libc = "0.2.8"
|
libc = "0.2.8"
|
||||||
|
|
||||||
|
|
79
src/color.rs
79
src/color.rs
|
@ -18,6 +18,7 @@ use std::io::{self, Write, Read};
|
||||||
use std::time::{SystemTime, Duration};
|
use std::time::{SystemTime, Duration};
|
||||||
use async::async_stdin;
|
use async::async_stdin;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use numtoa::NumToA;
|
||||||
|
|
||||||
/// A terminal color.
|
/// A terminal color.
|
||||||
pub trait Color {
|
pub trait Color {
|
||||||
|
@ -36,14 +37,24 @@ macro_rules! derive_color {
|
||||||
impl Color for $name {
|
impl Color for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("38;5;", $value, "m"))
|
f.write_str(self.fg_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("48;5;", $value, "m"))
|
f.write_str(self.bg_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
|
#[inline]
|
||||||
|
/// Returns the ANSI escape sequence as a string.
|
||||||
|
pub fn fg_str(&self) -> &'static str { csi!("38;5;", $value, "m") }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Returns the ANSI escape sequences as a string.
|
||||||
|
pub fn bg_str(&self) -> &'static str { csi!("48;5;", $value, "m") }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,15 +121,31 @@ impl AnsiValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AnsiValue {
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn fg_string(self) -> String {
|
||||||
|
let mut x = [0u8; 20];
|
||||||
|
let x = self.0.numtoa_str(10, &mut x);
|
||||||
|
[csi!("38;5;"), x, "m"].concat()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn bg_string(self) -> String {
|
||||||
|
let mut x = [0u8; 20];
|
||||||
|
let x = self.0.numtoa_str(10, &mut x);
|
||||||
|
[csi!("48;5;"), x, "m"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Color for AnsiValue {
|
impl Color for AnsiValue {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("38;5;{}m"), self.0)
|
f.write_str(&self.fg_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("48;5;{}m"), self.0)
|
f.write_str(&self.bg_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,15 +153,41 @@ impl Color for AnsiValue {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Rgb(pub u8, pub u8, pub u8);
|
pub struct Rgb(pub u8, pub u8, pub u8);
|
||||||
|
|
||||||
|
impl Rgb {
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn fg_string(self) -> String {
|
||||||
|
let (mut x, mut y, mut z) = ([0u8; 20], [0u8; 20], [0u8; 20]);
|
||||||
|
let (x, y, z) = (
|
||||||
|
self.0.numtoa_str(10, &mut x),
|
||||||
|
self.1.numtoa_str(10, &mut y),
|
||||||
|
self.2.numtoa_str(10, &mut z),
|
||||||
|
);
|
||||||
|
|
||||||
|
[csi!("38;2;"), x, ";", y, ";", z, "m"].concat()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn bg_string(self) -> String {
|
||||||
|
let (mut x, mut y, mut z) = ([0u8; 20], [0u8; 20], [0u8; 20]);
|
||||||
|
let (x, y, z) = (
|
||||||
|
self.0.numtoa_str(10, &mut x),
|
||||||
|
self.1.numtoa_str(10, &mut y),
|
||||||
|
self.2.numtoa_str(10, &mut z),
|
||||||
|
);
|
||||||
|
|
||||||
|
[csi!("48;2;"), x, ";", y, ";", z, "m"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Color for Rgb {
|
impl Color for Rgb {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("38;2;{};{};{}m"), self.0, self.1, self.2)
|
f.write_str(&self.fg_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("48;2;{};{};{}m"), self.0, self.1, self.2)
|
f.write_str(&self.bg_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,15 +195,25 @@ impl Color for Rgb {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Reset;
|
pub struct Reset;
|
||||||
|
|
||||||
|
const RESET_FG: &str = csi!("39m");
|
||||||
|
const RESET_BG: &str = csi!("49m");
|
||||||
|
|
||||||
|
impl Reset {
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn fg_str(self) -> &'static str { RESET_FG }
|
||||||
|
/// Returns the ANSI sequence as a string.
|
||||||
|
pub fn bg_str(self) -> &'static str { RESET_BG }
|
||||||
|
}
|
||||||
|
|
||||||
impl Color for Reset {
|
impl Color for Reset {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("39m"))
|
f.write_str(RESET_FG)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("49m"))
|
f.write_str(RESET_BG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::io::{self, Write, Error, ErrorKind, Read};
|
||||||
use async::async_stdin_until;
|
use async::async_stdin_until;
|
||||||
use std::time::{SystemTime, Duration};
|
use std::time::{SystemTime, Duration};
|
||||||
use raw::CONTROL_SEQUENCE_TIMEOUT;
|
use raw::CONTROL_SEQUENCE_TIMEOUT;
|
||||||
|
use numtoa::NumToA;
|
||||||
|
|
||||||
derive_csi_sequence!("Hide the cursor.", Hide, "?25l");
|
derive_csi_sequence!("Hide the cursor.", Hide, "?25l");
|
||||||
derive_csi_sequence!("Show the cursor.", Show, "?25h");
|
derive_csi_sequence!("Show the cursor.", Show, "?25h");
|
||||||
|
@ -32,6 +33,13 @@ derive_csi_sequence!("Save the cursor.", Save, "s");
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Goto(pub u16, pub u16);
|
pub struct Goto(pub u16, pub u16);
|
||||||
|
|
||||||
|
impl From<Goto> for String {
|
||||||
|
fn from(this: Goto) -> String {
|
||||||
|
let (mut x, mut y) = ([0u8; 20], [0u8; 20]);
|
||||||
|
["\x1B[", this.1.numtoa_str(10, &mut x), ";", this.0.numtoa_str(10, &mut y), "H"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Goto {
|
impl Default for Goto {
|
||||||
fn default() -> Goto {
|
fn default() -> Goto {
|
||||||
Goto(1, 1)
|
Goto(1, 1)
|
||||||
|
@ -41,8 +49,7 @@ impl Default for Goto {
|
||||||
impl fmt::Display for Goto {
|
impl fmt::Display for Goto {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
debug_assert!(self != &Goto(0, 0), "Goto is one-based.");
|
debug_assert!(self != &Goto(0, 0), "Goto is one-based.");
|
||||||
|
f.write_str(&String::from(*self))
|
||||||
write!(f, csi!("{};{}H"), self.1, self.0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,9 +57,16 @@ impl fmt::Display for Goto {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Left(pub u16);
|
pub struct Left(pub u16);
|
||||||
|
|
||||||
|
impl From<Left> for String {
|
||||||
|
fn from(this: Left) -> String {
|
||||||
|
let mut buf = [0u8; 20];
|
||||||
|
["\x1B[", this.0.numtoa_str(10, &mut buf), "D"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Left {
|
impl fmt::Display for Left {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("{}D"), self.0)
|
f.write_str(&String::from(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +74,16 @@ impl fmt::Display for Left {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Right(pub u16);
|
pub struct Right(pub u16);
|
||||||
|
|
||||||
|
impl From<Right> for String {
|
||||||
|
fn from(this: Right) -> String {
|
||||||
|
let mut buf = [0u8; 20];
|
||||||
|
["\x1B[", this.0.numtoa_str(10, &mut buf), "C"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Right {
|
impl fmt::Display for Right {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("{}C"), self.0)
|
f.write_str(&String::from(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +91,16 @@ impl fmt::Display for Right {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Up(pub u16);
|
pub struct Up(pub u16);
|
||||||
|
|
||||||
|
impl From<Up> for String {
|
||||||
|
fn from(this: Up) -> String {
|
||||||
|
let mut buf = [0u8; 20];
|
||||||
|
["\x1B[", this.0.numtoa_str(10, &mut buf), "A"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Up {
|
impl fmt::Display for Up {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("{}A"), self.0)
|
f.write_str(&String::from(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +108,16 @@ impl fmt::Display for Up {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct Down(pub u16);
|
pub struct Down(pub u16);
|
||||||
|
|
||||||
|
impl From<Down> for String {
|
||||||
|
fn from(this: Down) -> String {
|
||||||
|
let mut buf = [0u8; 20];
|
||||||
|
["\x1B[", this.0.numtoa_str(10, &mut buf), "B"].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Down {
|
impl fmt::Display for Down {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, csi!("{}B"), self.0)
|
f.write_str(&String::from(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +150,7 @@ impl<W: Write> DetectCursorPos for W {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if read_chars.len() == 0 {
|
if read_chars.is_empty() {
|
||||||
return Err(Error::new(ErrorKind::Other, "Cursor position detection timed out."));
|
return Err(Error::new(ErrorKind::Other, "Cursor position detection timed out."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
//! For more information refer to the [README](https://github.com/redox-os/termion).
|
//! For more information refer to the [README](https://github.com/redox-os/termion).
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
extern crate numtoa;
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
#[path="sys/redox/mod.rs"]
|
#[path="sys/redox/mod.rs"]
|
||||||
mod sys;
|
mod sys;
|
||||||
|
|
|
@ -15,5 +15,13 @@ macro_rules! derive_csi_sequence {
|
||||||
write!(f, csi!($value))
|
write!(f, csi!($value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for $name {
|
||||||
|
fn as_ref(&self) -> &'static [u8] { csi!($value).as_bytes() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for $name {
|
||||||
|
fn as_ref(&self) -> &'static str { csi!($value) }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue