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:
|
||||
script:
|
||||
- cargo +stable build --verbose
|
||||
- cargo +stable test --verbose
|
||||
- cargo +stable test --release --verbose
|
||||
- script -q -c "cargo +stable test --verbose"
|
||||
- script -q -c "cargo +stable test --release --verbose"
|
||||
|
||||
beta:
|
||||
script:
|
||||
- rustup toolchain add beta
|
||||
- cargo +beta build --verbose
|
||||
- cargo +beta test --verbose
|
||||
- cargo +beta test --release --verbose
|
||||
- script -q -c "cargo +beta test --verbose"
|
||||
- script -q -c "cargo +beta test --release --verbose"
|
||||
|
||||
nightly:
|
||||
script:
|
||||
- rustup toolchain add nightly
|
||||
- cargo +nightly build --verbose
|
||||
- cargo +nightly test --verbose
|
||||
- cargo +nightly test --release --verbose
|
||||
- script -q -c "cargo +nightly test --verbose"
|
||||
- script -q -c "cargo +nightly test --release --verbose"
|
||||
|
|
|
@ -9,6 +9,9 @@ license = "MIT"
|
|||
keywords = ["tty", "color", "terminal", "password", "tui"]
|
||||
exclude = ["target", "CHANGELOG.md", "image.png", "Cargo.lock"]
|
||||
|
||||
[dependencies]
|
||||
numtoa = { version = "0.1.0", features = ["std"]}
|
||||
|
||||
[target.'cfg(not(target_os = "redox"))'.dependencies]
|
||||
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 async::async_stdin;
|
||||
use std::env;
|
||||
use numtoa::NumToA;
|
||||
|
||||
/// A terminal color.
|
||||
pub trait Color {
|
||||
|
@ -36,14 +37,24 @@ macro_rules! derive_color {
|
|||
impl Color for $name {
|
||||
#[inline]
|
||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, csi!("38;5;", $value, "m"))
|
||||
f.write_str(self.fg_str())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 {
|
||||
#[inline]
|
||||
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]
|
||||
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)]
|
||||
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 {
|
||||
#[inline]
|
||||
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]
|
||||
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)]
|
||||
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 {
|
||||
#[inline]
|
||||
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, csi!("39m"))
|
||||
f.write_str(RESET_FG)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 std::time::{SystemTime, Duration};
|
||||
use raw::CONTROL_SEQUENCE_TIMEOUT;
|
||||
use numtoa::NumToA;
|
||||
|
||||
derive_csi_sequence!("Hide the cursor.", Hide, "?25l");
|
||||
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)]
|
||||
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 {
|
||||
fn default() -> Goto {
|
||||
Goto(1, 1)
|
||||
|
@ -41,8 +49,7 @@ impl Default for Goto {
|
|||
impl fmt::Display for Goto {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
debug_assert!(self != &Goto(0, 0), "Goto is one-based.");
|
||||
|
||||
write!(f, csi!("{};{}H"), self.1, self.0)
|
||||
f.write_str(&String::from(*self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,9 +57,16 @@ impl fmt::Display for Goto {
|
|||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
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 {
|
||||
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)]
|
||||
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 {
|
||||
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)]
|
||||
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 {
|
||||
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)]
|
||||
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 {
|
||||
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."));
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
//! For more information refer to the [README](https://github.com/redox-os/termion).
|
||||
#![warn(missing_docs)]
|
||||
|
||||
extern crate numtoa;
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
#[path="sys/redox/mod.rs"]
|
||||
mod sys;
|
||||
|
|
|
@ -15,5 +15,13 @@ macro_rules! derive_csi_sequence {
|
|||
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