use crate::primitives::termtui::screen::Screen;
use crate::primitives::termtui::size::Size;
use std::io::Write;
use termwiz::escape::parser::Parser as TermwizParser;
pub struct Parser {
parser: TermwizParser,
screen: Screen,
}
impl Parser {
pub fn new(rows: usize, cols: usize, scrollback: usize) -> Self {
Self {
parser: TermwizParser::new(),
screen: Screen::new(rows, cols, scrollback),
}
}
pub fn process(&mut self, bytes: &[u8]) {
self.parser.parse(bytes, |action| {
self.screen.handle_action(action);
});
}
pub fn screen(&self) -> &Screen {
&self.screen
}
pub fn screen_mut(&mut self) -> &mut Screen {
&mut self.screen
}
pub fn resize(&mut self, rows: usize, cols: usize) {
self.screen.resize(rows, cols);
}
pub fn size(&self) -> Size {
self.screen.size()
}
pub fn scrollback(&self) -> usize {
self.screen.scrollback()
}
pub fn set_scrollback(&mut self, offset: usize) {
self.screen.set_scrollback(offset);
}
}
impl Write for Parser {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.process(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parser_new() {
let parser = Parser::new(24, 80, 1000);
assert_eq!(parser.size().rows, 24);
assert_eq!(parser.size().cols, 80);
}
#[test]
fn test_parser_process_text() {
let mut parser = Parser::new(24, 80, 1000);
parser.process(b"Hello");
assert_eq!(parser.screen().cursor_pos().col, 5);
}
#[test]
fn test_parser_process_escape() {
let mut parser = Parser::new(24, 80, 1000);
parser.process(b"\x1b[2;3H");
assert_eq!(parser.screen().cursor_pos().row, 1); assert_eq!(parser.screen().cursor_pos().col, 2); }
#[test]
fn test_parser_write_trait() {
let mut parser = Parser::new(24, 80, 1000);
write!(parser, "Test").unwrap();
assert_eq!(parser.screen().cursor_pos().col, 4);
}
#[test]
fn test_parser_resize() {
let mut parser = Parser::new(24, 80, 1000);
parser.resize(40, 120);
assert_eq!(parser.size().rows, 40);
assert_eq!(parser.size().cols, 120);
}
}