Merge branch 'daniel.buga/ansi-parser-escape' into master
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2,7 +2,7 @@
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ansi-parser"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
dependencies = [
|
||||
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@@ -4,6 +4,7 @@ mod tests;
|
||||
///The following are the implemented ANSI escape sequences. More to be added.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum AnsiSequence {
|
||||
Escape,
|
||||
CursorPos(u32, u32),
|
||||
CursorUp(u32),
|
||||
CursorDown(u32),
|
||||
@@ -61,6 +62,7 @@ impl Display for AnsiSequence {
|
||||
|
||||
use AnsiSequence::*;
|
||||
match self {
|
||||
Escape => write!(formatter, "\u{1b}"),
|
||||
CursorPos(line, col)
|
||||
=> write!(formatter, "[{};{}H", line, col),
|
||||
CursorUp(amt)
|
||||
|
@@ -26,27 +26,45 @@ named!(
|
||||
)
|
||||
);
|
||||
|
||||
// TODO kind of ugly, would prefer to pass in the default so we could use it for
|
||||
// all escapes with defaults (not just those that default to 1).
|
||||
named!(
|
||||
parse_def_cursor_int<&str, u32>,
|
||||
map!(
|
||||
nom::digit0,
|
||||
|s: &str| s.parse::<u32>().unwrap_or(1)
|
||||
)
|
||||
);
|
||||
|
||||
named!(
|
||||
cursor_pos<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
x: parse_int >>
|
||||
tag!(";") >>
|
||||
y: parse_int >>
|
||||
tag!("[") >>
|
||||
x: parse_def_cursor_int >>
|
||||
opt!(tag!(";")) >>
|
||||
y: parse_def_cursor_int >>
|
||||
alt!(
|
||||
tag!("H") |
|
||||
tag!("H") |
|
||||
tag!("f")
|
||||
) >>
|
||||
(AnsiSequence::CursorPos(x, y))
|
||||
)
|
||||
);
|
||||
|
||||
named!(
|
||||
escape<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("\u{1b}") >>
|
||||
(AnsiSequence::Escape)
|
||||
)
|
||||
);
|
||||
|
||||
named!(
|
||||
cursor_up<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
am: parse_int >>
|
||||
tag!("A") >>
|
||||
tag!("[") >>
|
||||
am: parse_def_cursor_int >>
|
||||
tag!("A") >>
|
||||
(AnsiSequence::CursorUp(am))
|
||||
)
|
||||
);
|
||||
@@ -54,9 +72,9 @@ named!(
|
||||
named!(
|
||||
cursor_down<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
am: parse_int >>
|
||||
tag!("B") >>
|
||||
tag!("[") >>
|
||||
am: parse_def_cursor_int >>
|
||||
tag!("B") >>
|
||||
(AnsiSequence::CursorDown(am))
|
||||
)
|
||||
);
|
||||
@@ -64,9 +82,9 @@ named!(
|
||||
named!(
|
||||
cursor_forward<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
am: parse_int >>
|
||||
tag!("C") >>
|
||||
tag!("[") >>
|
||||
am: parse_def_cursor_int >>
|
||||
tag!("C") >>
|
||||
(AnsiSequence::CursorForward(am))
|
||||
)
|
||||
);
|
||||
@@ -74,9 +92,9 @@ named!(
|
||||
named!(
|
||||
cursor_backward<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
am: parse_int >>
|
||||
tag!("D") >>
|
||||
tag!("[") >>
|
||||
am: parse_def_cursor_int >>
|
||||
tag!("D") >>
|
||||
(AnsiSequence::CursorBackward(am))
|
||||
)
|
||||
);
|
||||
@@ -125,6 +143,26 @@ named!(
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
named!(
|
||||
graphics_mode5<&str, AnsiSequence>,
|
||||
do_parse!(
|
||||
tag!("[") >>
|
||||
val1: parse_int >>
|
||||
tag!(";") >>
|
||||
val2: parse_int >>
|
||||
tag!(";") >>
|
||||
val3: parse_int >>
|
||||
tag!(";") >>
|
||||
val4: parse_int >>
|
||||
tag!(";") >>
|
||||
val5: parse_int >>
|
||||
tag!("m") >>
|
||||
(AnsiSequence::SetGraphicsMode(vec![val1, val2, val3, val4, val5]))
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
named!(
|
||||
graphics_mode<&str, AnsiSequence>,
|
||||
alt!(
|
||||
@@ -132,6 +170,7 @@ named!(
|
||||
| graphics_mode2
|
||||
| graphics_mode3
|
||||
| graphics_mode4
|
||||
| graphics_mode5
|
||||
)
|
||||
);
|
||||
|
||||
@@ -213,11 +252,12 @@ tag_parser!(set_single_shift3, "O", AnsiSequence::SetSingleShift3);
|
||||
named!(
|
||||
combined<&str, AnsiSequence>,
|
||||
alt!(
|
||||
cursor_pos
|
||||
escape
|
||||
| cursor_pos
|
||||
| cursor_up
|
||||
| cursor_down
|
||||
| cursor_forward
|
||||
| cursor_backward
|
||||
| cursor_backward
|
||||
| cursor_save
|
||||
| cursor_restore
|
||||
| erase_display
|
||||
@@ -272,4 +312,3 @@ named!(
|
||||
(Output::Escape(seq))
|
||||
)
|
||||
);
|
||||
|
||||
|
@@ -21,13 +21,37 @@ macro_rules! test_parser {
|
||||
}
|
||||
}
|
||||
|
||||
test_parser!(cursor_pos, "\u{1b}[10;5H");
|
||||
test_parser!(cursor_up, "\u{1b}[5A");
|
||||
test_parser!(cursor_down, "\u{1b}[5B");
|
||||
test_parser!(cursor_forward, "\u{1b}[5C");
|
||||
test_parser!(cursor_backward,"\u{1b}[5D");
|
||||
test_parser!(cursor_save, "\u{1b}[s");
|
||||
test_parser!(cursor_restore, "\u{1b}[u");
|
||||
macro_rules! test_def_val_parser {
|
||||
($name:ident, $string:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut buff = String::new();
|
||||
let ret = parse_escape($string);
|
||||
|
||||
assert!(ret.is_ok());
|
||||
let ret = ret.unwrap().1;
|
||||
|
||||
write!(&mut buff, "{}", ret)
|
||||
.unwrap();
|
||||
|
||||
let ret2 = parse_escape(&buff);
|
||||
assert!(ret2.is_ok());
|
||||
|
||||
let ret2 = ret2.unwrap().1;
|
||||
assert_eq!(ret, ret2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_def_val_parser!(cursor_pos_default, "\u{1b}[H");
|
||||
test_def_val_parser!(cursor_pos, "\u{1b}[10;5H");
|
||||
test_def_val_parser!(cursor_up_default, "\u{1b}[A");
|
||||
test_def_val_parser!(cursor_up, "\u{1b}[5A");
|
||||
test_def_val_parser!(cursor_down, "\u{1b}[5B");
|
||||
test_def_val_parser!(cursor_forward, "\u{1b}[5C");
|
||||
test_def_val_parser!(cursor_backward, "\u{1b}[5D");
|
||||
test_parser!(cursor_save, "\u{1b}[s");
|
||||
test_parser!(cursor_restore, "\u{1b}[u");
|
||||
|
||||
test_parser!(erase_display, "\u{1b}[2J");
|
||||
test_parser!(erase_line, "\u{1b}[K");
|
||||
@@ -96,3 +120,28 @@ fn test_parser_iterator_failure() {
|
||||
|
||||
assert_eq!(strings.len(), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_value() {
|
||||
let strings: Vec<_> = "\x1b[H\x1b[123456H\x1b[;123456H\x1b[7asd;1234H\x1b[a;sd7H"
|
||||
.ansi_parse()
|
||||
.collect();
|
||||
assert_eq!(strings.len(), 5);
|
||||
assert_eq!(strings[0], Output::Escape(AnsiSequence::CursorPos(1,1)));
|
||||
assert_eq!(strings[1], Output::Escape(AnsiSequence::CursorPos(123456,1)));
|
||||
assert_eq!(strings[2], Output::Escape(AnsiSequence::CursorPos(1,123456)));
|
||||
assert_eq!(strings[3], Output::TextBlock("\x1b[7asd;1234H"));
|
||||
assert_eq!(strings[4], Output::TextBlock("\x1b[a;sd7H"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape() {
|
||||
let parts: Vec<_> = "\x1b\x1b[33mFoobar".ansi_parse().collect();
|
||||
assert_eq!(
|
||||
parts,
|
||||
vec![
|
||||
Output::Escape(AnsiSequence::Escape),
|
||||
Output::TextBlock("[33mFoobar")
|
||||
]
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user