Fix #24, make use of Result instead
This commit is contained in:
parent
119cbda718
commit
11225e561d
|
@ -1,6 +1,5 @@
|
||||||
extern crate termion;
|
extern crate termion;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
fn main() {
|
fn main() {
|
||||||
use termion::{TermRead, TermWrite, IntoRawMode, Key};
|
use termion::{TermRead, TermWrite, IntoRawMode, Key};
|
||||||
|
@ -18,7 +17,7 @@ fn main() {
|
||||||
for c in stdin.keys() {
|
for c in stdin.keys() {
|
||||||
stdout.goto(5, 5).unwrap();
|
stdout.goto(5, 5).unwrap();
|
||||||
stdout.clear_line().unwrap();
|
stdout.clear_line().unwrap();
|
||||||
match c {
|
match c.unwrap() {
|
||||||
Key::Char('q') => break,
|
Key::Char('q') => break,
|
||||||
Key::Char(c) => println!("{}", c),
|
Key::Char(c) => println!("{}", c),
|
||||||
Key::Alt(c) => println!("^{}", c),
|
Key::Alt(c) => println!("^{}", c),
|
||||||
|
@ -29,7 +28,6 @@ fn main() {
|
||||||
Key::Down => println!("↓"),
|
Key::Down => println!("↓"),
|
||||||
Key::Backspace => println!("×"),
|
Key::Backspace => println!("×"),
|
||||||
Key::Invalid => println!("???"),
|
Key::Invalid => println!("???"),
|
||||||
Key::Error(_) => println!("ERROR"),
|
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
stdout.flush().unwrap();
|
stdout.flush().unwrap();
|
||||||
|
@ -37,6 +35,7 @@ fn main() {
|
||||||
|
|
||||||
stdout.show_cursor().unwrap();
|
stdout.show_cursor().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("To run this example, you need to enable the `nightly` feature. Use Rust nightly and compile with `--features nightly`.")
|
println!("To run this example, you need to enable the `nightly` feature. Use Rust nightly and compile with `--features nightly`.")
|
||||||
|
|
|
@ -156,6 +156,7 @@ mod test {
|
||||||
buf.csi(b"blah").unwrap();
|
buf.csi(b"blah").unwrap();
|
||||||
assert_eq!(buf.get_ref(), b"\x1B[bluh\x1B[blah");
|
assert_eq!(buf.get_ref(), b"\x1B[bluh\x1B[blah");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_csi_partial() {
|
fn test_csi_partial() {
|
||||||
let mut buf = [0; 3];
|
let mut buf = [0; 3];
|
||||||
|
@ -164,6 +165,7 @@ mod test {
|
||||||
assert_eq!(buf.csi(b"").unwrap(), 0);
|
assert_eq!(buf.csi(b"").unwrap(), 0);
|
||||||
assert_eq!(buf.csi(b"nooooo").unwrap(), 0);
|
assert_eq!(buf.csi(b"nooooo").unwrap(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_osc() {
|
fn test_osc() {
|
||||||
let mut buf = Cursor::new(Vec::new());
|
let mut buf = Cursor::new(Vec::new());
|
||||||
|
@ -174,6 +176,7 @@ mod test {
|
||||||
buf.osc(b"blah").unwrap();
|
buf.osc(b"blah").unwrap();
|
||||||
assert_eq!(buf.get_ref(), b"\x1B]bluh\x1B]blah");
|
assert_eq!(buf.get_ref(), b"\x1B]bluh\x1B]blah");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_osc_partial() {
|
fn test_osc_partial() {
|
||||||
let mut buf = [0; 3];
|
let mut buf = [0; 3];
|
||||||
|
@ -182,6 +185,7 @@ mod test {
|
||||||
assert_eq!(buf.osc(b"").unwrap(), 0);
|
assert_eq!(buf.osc(b"").unwrap(), 0);
|
||||||
assert_eq!(buf.osc(b"nooooo").unwrap(), 0);
|
assert_eq!(buf.osc(b"nooooo").unwrap(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dsc() {
|
fn test_dsc() {
|
||||||
let mut buf = Cursor::new(Vec::new());
|
let mut buf = Cursor::new(Vec::new());
|
||||||
|
@ -192,6 +196,7 @@ mod test {
|
||||||
buf.dsc(b"blah").unwrap();
|
buf.dsc(b"blah").unwrap();
|
||||||
assert_eq!(buf.get_ref(), b"\x1BPbluh\x1BPblah");
|
assert_eq!(buf.get_ref(), b"\x1BPbluh\x1BPblah");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dsc_partial() {
|
fn test_dsc_partial() {
|
||||||
let mut buf = [0; 3];
|
let mut buf = [0; 3];
|
||||||
|
@ -200,6 +205,7 @@ mod test {
|
||||||
assert_eq!(buf.dsc(b"").unwrap(), 0);
|
assert_eq!(buf.dsc(b"").unwrap(), 0);
|
||||||
assert_eq!(buf.dsc(b"nooooo").unwrap(), 0);
|
assert_eq!(buf.dsc(b"nooooo").unwrap(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clear() {
|
fn test_clear() {
|
||||||
let mut buf = Cursor::new(Vec::new());
|
let mut buf = Cursor::new(Vec::new());
|
||||||
|
@ -208,6 +214,7 @@ mod test {
|
||||||
buf.clear().unwrap();
|
buf.clear().unwrap();
|
||||||
assert_eq!(buf.get_ref(), b"\x1B[2J\x1B[2J");
|
assert_eq!(buf.get_ref(), b"\x1B[2J\x1B[2J");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_goto() {
|
fn test_goto() {
|
||||||
let mut buf = Cursor::new(Vec::new());
|
let mut buf = Cursor::new(Vec::new());
|
||||||
|
@ -216,6 +223,7 @@ mod test {
|
||||||
buf.goto(24, 45).unwrap();
|
buf.goto(24, 45).unwrap();
|
||||||
assert_eq!(buf.get_ref(), b"\x1B[00044;00035H\x1B[00046;00025H");
|
assert_eq!(buf.get_ref(), b"\x1B[00044;00035H\x1B[00046;00025H");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_style() {
|
fn test_style() {
|
||||||
use Style;
|
use Style;
|
||||||
|
|
53
src/input.rs
53
src/input.rs
|
@ -2,11 +2,8 @@ use std::io::{self, Read, Write};
|
||||||
|
|
||||||
use IntoRawMode;
|
use IntoRawMode;
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
|
||||||
use std::io::{Chars, CharsError};
|
|
||||||
|
|
||||||
/// A key.
|
/// A key.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
/// Backspace.
|
/// Backspace.
|
||||||
Backspace,
|
Backspace,
|
||||||
|
@ -28,8 +25,6 @@ pub enum Key {
|
||||||
Ctrl(char),
|
Ctrl(char),
|
||||||
/// Invalid character code.
|
/// Invalid character code.
|
||||||
Invalid,
|
Invalid,
|
||||||
/// IO error.
|
|
||||||
Error(io::Error),
|
|
||||||
/// Null byte.
|
/// Null byte.
|
||||||
Null,
|
Null,
|
||||||
|
|
||||||
|
@ -45,12 +40,12 @@ pub struct Keys<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
impl<I: Iterator<Item = Result<char, CharsError>>> Iterator for Keys<I> {
|
impl<I: Iterator<Item = Result<char, io::CharsError>>> Iterator for Keys<I> {
|
||||||
type Item = Key;
|
type Item = Result<Key, io::CharsError>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Key> {
|
fn next(&mut self) -> Option<Result<Key, io::CharsError>> {
|
||||||
match self.chars.next() {
|
Some(match self.chars.next() {
|
||||||
Some(Ok('\x1B')) => Some(match self.chars.next() {
|
Some(Ok('\x1B')) => Ok(match self.chars.next() {
|
||||||
Some(Ok('[')) => match self.chars.next() {
|
Some(Ok('[')) => match self.chars.next() {
|
||||||
Some(Ok('D')) => Key::Left,
|
Some(Ok('D')) => Key::Left,
|
||||||
Some(Ok('C')) => Key::Right,
|
Some(Ok('C')) => Key::Right,
|
||||||
|
@ -61,16 +56,16 @@ impl<I: Iterator<Item = Result<char, CharsError>>> Iterator for Keys<I> {
|
||||||
Some(Ok(c)) => Key::Alt(c),
|
Some(Ok(c)) => Key::Alt(c),
|
||||||
Some(Err(_)) | None => Key::Invalid,
|
Some(Err(_)) | None => Key::Invalid,
|
||||||
}),
|
}),
|
||||||
Some(Ok('\n')) | Some(Ok('\r')) => Some(Key::Char('\n')),
|
Some(Ok('\n')) | Some(Ok('\r')) => Ok(Key::Char('\n')),
|
||||||
Some(Ok('\t')) => Some(Key::Char('\t')),
|
Some(Ok('\t')) => Ok(Key::Char('\t')),
|
||||||
Some(Ok('\x7F')) => Some(Key::Backspace),
|
Some(Ok('\x7F')) => Ok(Key::Backspace),
|
||||||
Some(Ok(c @ '\x01' ... '\x1A')) => Some(Key::Ctrl((c as u8 - 0x1 + b'a') as char)),
|
Some(Ok(c @ '\x01' ... '\x1A')) => Ok(Key::Ctrl((c as u8 - 0x1 + b'a') as char)),
|
||||||
Some(Ok(c @ '\x1C' ... '\x1F')) => Some(Key::Ctrl((c as u8 - 0x1C + b'4') as char)),
|
Some(Ok(c @ '\x1C' ... '\x1F')) => Ok(Key::Ctrl((c as u8 - 0x1C + b'4') as char)),
|
||||||
None => None,
|
Some(Ok('\0')) => Ok(Key::Null),
|
||||||
Some(Ok('\0')) => Some(Key::Null),
|
Some(Ok(c)) => Ok(Key::Char(c)),
|
||||||
Some(Ok(c)) => Some(Key::Char(c)),
|
Some(Err(e)) => Err(e),
|
||||||
Some(Err(e)) => Some(Key::Error(io::Error::new(io::ErrorKind::InvalidData, e))),
|
None => return None,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +73,7 @@ impl<I: Iterator<Item = Result<char, CharsError>>> Iterator for Keys<I> {
|
||||||
pub trait TermRead {
|
pub trait TermRead {
|
||||||
/// An iterator over key inputs.
|
/// An iterator over key inputs.
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
fn keys(self) -> Keys<Chars<Self>> where Self: Sized;
|
fn keys(self) -> Keys<io::Chars<Self>> where Self: Sized;
|
||||||
|
|
||||||
/// Read a line.
|
/// Read a line.
|
||||||
///
|
///
|
||||||
|
@ -99,7 +94,7 @@ pub trait TermRead {
|
||||||
|
|
||||||
impl<R: Read> TermRead for R {
|
impl<R: Read> TermRead for R {
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
fn keys(self) -> Keys<Chars<R>> {
|
fn keys(self) -> Keys<io::Chars<R>> {
|
||||||
Keys {
|
Keys {
|
||||||
chars: self.chars(),
|
chars: self.chars(),
|
||||||
}
|
}
|
||||||
|
@ -133,12 +128,12 @@ mod test {
|
||||||
fn test_keys() {
|
fn test_keys() {
|
||||||
let mut i = b"\x1Bayo\x7F\x1B[D".keys();
|
let mut i = b"\x1Bayo\x7F\x1B[D".keys();
|
||||||
|
|
||||||
assert_eq!(i.next(), Some(Key::Alt('a')));
|
assert_eq!(i.next().unwrap().unwrap(), Key::Alt('a'));
|
||||||
assert_eq!(i.next(), Some(Key::Char('y')));
|
assert_eq!(i.next().unwrap().unwrap(), Key::Char('y'));
|
||||||
assert_eq!(i.next(), Some(Key::Char('o')));
|
assert_eq!(i.next().unwrap().unwrap(), Key::Char('o'));
|
||||||
assert_eq!(i.next(), Some(Key::Backspace));
|
assert_eq!(i.next().unwrap().unwrap(), Key::Backspace);
|
||||||
assert_eq!(i.next(), Some(Key::Left));
|
assert_eq!(i.next().unwrap().unwrap(), Key::Left);
|
||||||
assert_eq!(i.next(), None);
|
assert!(i.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn line_match(a: &str, b: Option<&str>) {
|
fn line_match(a: &str, b: Option<&str>) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct RawTerminal<W: Write> {
|
||||||
impl<W: Write> Drop for RawTerminal<W> {
|
impl<W: Write> Drop for RawTerminal<W> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
use control::TermWrite;
|
use control::TermWrite;
|
||||||
let _ = self.csi(b"R");
|
self.csi(b"R").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue