334 lines
9.0 KiB
Rust
334 lines
9.0 KiB
Rust
#[cfg(test)]
|
|
mod tests;
|
|
|
|
use crate::AnsiSequence;
|
|
|
|
use core::convert::TryInto;
|
|
use heapless::Vec;
|
|
use nom::*;
|
|
|
|
macro_rules! tag_parser {
|
|
($sig:ident, $tag:expr, $ret:expr) => {
|
|
named!(
|
|
$sig<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!($tag) >>
|
|
($ret)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
named!(
|
|
parse_int<&str, u32>,
|
|
map_res!(
|
|
nom::digit,
|
|
|s: &str| s.parse::<u32>()
|
|
)
|
|
);
|
|
|
|
// 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_def_cursor_int >>
|
|
opt!(tag!(";")) >>
|
|
y: parse_def_cursor_int >>
|
|
alt!(
|
|
tag!("H") |
|
|
tag!("f")
|
|
) >>
|
|
(AnsiSequence::CursorPos(x, y))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
cursor_up<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
am: parse_def_cursor_int >>
|
|
tag!("A") >>
|
|
(AnsiSequence::CursorUp(am))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
cursor_down<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
am: parse_def_cursor_int >>
|
|
tag!("B") >>
|
|
(AnsiSequence::CursorDown(am))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
cursor_forward<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
am: parse_def_cursor_int >>
|
|
tag!("C") >>
|
|
(AnsiSequence::CursorForward(am))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
cursor_backward<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
am: parse_def_cursor_int >>
|
|
tag!("D") >>
|
|
(AnsiSequence::CursorBackward(am))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
graphics_mode1<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
val: parse_int >>
|
|
tag!("m") >>
|
|
val: expr_res!(val.try_into()) >>
|
|
conv: expr_res!(Vec::from_slice(&[val])) >>
|
|
(AnsiSequence::SetGraphicsMode(conv))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
graphics_mode2<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
val1: parse_int >>
|
|
tag!(";") >>
|
|
val2: parse_int >>
|
|
tag!("m") >>
|
|
val1: expr_res!(val1.try_into()) >>
|
|
val2: expr_res!(val2.try_into()) >>
|
|
conv: expr_res!(Vec::from_slice(&[
|
|
val1,
|
|
val2,
|
|
])) >>
|
|
(AnsiSequence::SetGraphicsMode(conv))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
graphics_mode3<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
val1: parse_int >>
|
|
tag!(";") >>
|
|
val2: parse_int >>
|
|
tag!(";") >>
|
|
val3: parse_int >>
|
|
tag!("m") >>
|
|
val1: expr_res!(val1.try_into()) >>
|
|
val2: expr_res!(val2.try_into()) >>
|
|
val3: expr_res!(val3.try_into()) >>
|
|
conv: expr_res!(Vec::from_slice(&[
|
|
val1,
|
|
val2,
|
|
val3,
|
|
])) >>
|
|
(AnsiSequence::SetGraphicsMode(conv))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
graphics_mode4<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[m") >>
|
|
(AnsiSequence::SetGraphicsMode(Vec::new()))
|
|
)
|
|
);
|
|
|
|
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") >>
|
|
val1: expr_res!(val1.try_into()) >>
|
|
val2: expr_res!(val2.try_into()) >>
|
|
val3: expr_res!(val3.try_into()) >>
|
|
val4: expr_res!(val4.try_into()) >>
|
|
val5: expr_res!(val5.try_into()) >>
|
|
conv: expr_res!(Vec::from_slice(&[
|
|
val1,
|
|
val2,
|
|
val3,
|
|
val4,
|
|
val5,
|
|
])) >>
|
|
(AnsiSequence::SetGraphicsMode(conv))
|
|
)
|
|
);
|
|
|
|
|
|
named!(
|
|
graphics_mode<&str, AnsiSequence>,
|
|
alt!(
|
|
graphics_mode1
|
|
| graphics_mode2
|
|
| graphics_mode3
|
|
| graphics_mode4
|
|
| graphics_mode5
|
|
)
|
|
);
|
|
|
|
named!(
|
|
set_mode<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[=") >>
|
|
mode: parse_int >>
|
|
conv: expr_res!(mode.try_into()) >>
|
|
tag!("h") >>
|
|
(AnsiSequence::SetMode(conv))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
reset_mode<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[=") >>
|
|
mode: parse_int >>
|
|
conv: expr_res!(mode.try_into()) >>
|
|
tag!("l") >>
|
|
(AnsiSequence::ResetMode(conv))
|
|
)
|
|
);
|
|
|
|
named!(
|
|
set_top_and_bottom<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("[") >>
|
|
x: parse_int >>
|
|
tag!(";") >>
|
|
y: parse_int >>
|
|
tag!("r") >>
|
|
(AnsiSequence::SetTopAndBottom(x, y))
|
|
)
|
|
);
|
|
|
|
tag_parser!(cursor_save, "[s", AnsiSequence::CursorSave);
|
|
tag_parser!(cursor_restore, "[u", AnsiSequence::CursorRestore);
|
|
tag_parser!(erase_display, "[2J", AnsiSequence::EraseDisplay);
|
|
tag_parser!(erase_line, "[K", AnsiSequence::EraseLine);
|
|
tag_parser!(hide_cursor, "[?25l", AnsiSequence::HideCursor);
|
|
tag_parser!(show_cursor, "[?25h", AnsiSequence::ShowCursor);
|
|
tag_parser!(cursor_to_app, "[?1h", AnsiSequence::CursorToApp);
|
|
tag_parser!(set_new_line_mode, "[20h", AnsiSequence::SetNewLineMode);
|
|
tag_parser!(set_col_132, "[?3h", AnsiSequence::SetCol132);
|
|
tag_parser!(set_smooth_scroll, "[?4h", AnsiSequence::SetSmoothScroll);
|
|
tag_parser!(set_reverse_video, "[?5h", AnsiSequence::SetReverseVideo);
|
|
tag_parser!(set_origin_rel, "[?6h", AnsiSequence::SetOriginRelative);
|
|
tag_parser!(set_auto_wrap, "[?7h", AnsiSequence::SetAutoWrap);
|
|
tag_parser!(set_auto_repeat, "[?8h", AnsiSequence::SetAutoRepeat);
|
|
tag_parser!(set_interlacing, "[?9h", AnsiSequence::SetInterlacing);
|
|
tag_parser!(set_linefeed, "[20l", AnsiSequence::SetLineFeedMode);
|
|
tag_parser!(set_cursorkey, "[?1l", AnsiSequence::SetCursorKeyToCursor);
|
|
tag_parser!(set_vt52, "[?2l", AnsiSequence::SetVT52);
|
|
tag_parser!(set_col80, "[?3l", AnsiSequence::SetCol80);
|
|
tag_parser!(set_jump_scroll, "[?4l", AnsiSequence::SetJumpScrolling);
|
|
tag_parser!(set_normal_video, "[?5l", AnsiSequence::SetNormalVideo);
|
|
tag_parser!(set_origin_abs, "[?6l", AnsiSequence::SetOriginAbsolute);
|
|
tag_parser!(reset_auto_wrap, "[?7l", AnsiSequence::ResetAutoWrap);
|
|
tag_parser!(reset_auto_repeat, "[?8l", AnsiSequence::ResetAutoRepeat);
|
|
tag_parser!(reset_interlacing, "[?9l", AnsiSequence::ResetInterlacing);
|
|
|
|
tag_parser!(set_alternate_keypad, "=", AnsiSequence::SetAlternateKeypad);
|
|
tag_parser!(set_numeric_keypad, ">", AnsiSequence::SetNumericKeypad);
|
|
tag_parser!(set_uk_g0, "(A", AnsiSequence::SetUKG0);
|
|
tag_parser!(set_uk_g1, ")A", AnsiSequence::SetUKG1);
|
|
tag_parser!(set_us_g0, "(B", AnsiSequence::SetUSG0);
|
|
tag_parser!(set_us_g1, ")B", AnsiSequence::SetUSG1);
|
|
tag_parser!(set_g0_special, "(0", AnsiSequence::SetG0SpecialChars);
|
|
tag_parser!(set_g1_special, ")0", AnsiSequence::SetG1SpecialChars);
|
|
tag_parser!(set_g0_alternate, "(1", AnsiSequence::SetG0AlternateChar);
|
|
tag_parser!(set_g1_alternate, ")1", AnsiSequence::SetG1AlternateChar);
|
|
tag_parser!(set_g0_graph, "(2", AnsiSequence::SetG0AltAndSpecialGraph);
|
|
tag_parser!(set_g1_graph, ")2", AnsiSequence::SetG1AltAndSpecialGraph);
|
|
tag_parser!(set_single_shift2, "N", AnsiSequence::SetSingleShift2);
|
|
tag_parser!(set_single_shift3, "O", AnsiSequence::SetSingleShift3);
|
|
|
|
named!(
|
|
combined<&str, AnsiSequence>,
|
|
alt!(
|
|
cursor_pos
|
|
| cursor_up
|
|
| cursor_down
|
|
| cursor_forward
|
|
| cursor_backward
|
|
| cursor_save
|
|
| cursor_restore
|
|
| erase_display
|
|
| erase_line
|
|
| graphics_mode
|
|
| set_mode
|
|
| reset_mode
|
|
| hide_cursor
|
|
| show_cursor
|
|
| cursor_to_app
|
|
| set_new_line_mode
|
|
| set_col_132
|
|
| set_smooth_scroll
|
|
| set_reverse_video
|
|
| set_origin_rel
|
|
| set_auto_wrap
|
|
| set_auto_repeat
|
|
| set_interlacing
|
|
| set_linefeed
|
|
| set_cursorkey
|
|
| set_vt52
|
|
| set_col80
|
|
| set_jump_scroll
|
|
| set_normal_video
|
|
| set_origin_abs
|
|
| reset_auto_wrap
|
|
| reset_auto_repeat
|
|
| reset_interlacing
|
|
| set_top_and_bottom
|
|
| set_alternate_keypad
|
|
| set_numeric_keypad
|
|
| set_uk_g0
|
|
| set_uk_g1
|
|
| set_us_g0
|
|
| set_us_g1
|
|
| set_g0_special
|
|
| set_g1_special
|
|
| set_g0_alternate
|
|
| set_g1_alternate
|
|
| set_g0_graph
|
|
| set_g1_graph
|
|
| set_single_shift2
|
|
| set_single_shift3
|
|
)
|
|
);
|
|
|
|
named!(
|
|
pub parse_escape<&str, AnsiSequence>,
|
|
do_parse!(
|
|
tag!("\u{1b}") >>
|
|
seq: combined >>
|
|
(seq)
|
|
)
|
|
);
|