use std::io::{Result, Write};
pub struct TermOut {
buf: Vec<u8>,
flush_to: usize,
features: Features,
size: (i32, i32),
pub(crate) new_cleanup: Option<Vec<u8>>,
}
impl TermOut {
pub(crate) fn new(features: Features) -> Self {
Self {
buf: Vec::new(),
flush_to: 0,
features,
new_cleanup: None,
size: (0, 0),
}
}
pub fn features(&self) -> &Features {
&self.features
}
pub fn size(&self) -> (i32, i32) {
self.size
}
pub fn flush(&mut self) {
self.flush_to = self.buf.len();
}
#[inline]
pub fn out(&mut self, data: &[u8]) {
self.buf.extend_from_slice(data);
}
pub fn out1(&mut self, v1: u8) {
self.buf.push(v1);
}
pub fn out2(&mut self, v1: u8, v2: u8) {
self.buf.push(v1);
self.buf.push(v2);
}
pub fn out3(&mut self, v1: u8, v2: u8, v3: u8) {
self.buf.push(v1);
self.buf.push(v2);
self.buf.push(v3);
}
pub fn out_num(&mut self, v: i32) {
if v <= 0 {
self.out1(b'0');
} else if v <= 9 {
self.out1(v as u8 + b'0');
} else if v <= 99 {
self.out2((v / 10) as u8 + b'0', (v % 10) as u8 + b'0');
} else if v <= 999 {
self.out3(
(v / 100) as u8 + b'0',
(v / 10 % 10) as u8 + b'0',
(v % 10) as u8 + b'0',
);
} else {
self.out3(b'9', b'9', b'9');
}
}
pub fn to(&mut self, y: i32, x: i32) {
self.out2(27, b'[');
self.out_num(y + 1);
self.out1(b';');
self.out_num(x + 1);
self.out1(b'H');
}
pub fn underline_cursor(&mut self) {
self.out(b"\x1B[34h");
}
pub fn block_cursor(&mut self) {
self.out(b"\x1B[34l");
}
pub fn show_cursor(&mut self) {
self.out(b"\x1B[?25h\x1B[?0c");
}
pub fn hide_cursor(&mut self) {
self.out(b"\x1B[?25l\x1B[?1c");
}
pub fn origin(&mut self) {
self.out(b"\x1B[H");
}
pub fn erase_eol(&mut self) {
self.out(b"\x1B[K");
}
pub fn erase_eod(&mut self) {
self.out(b"\x1B[J");
}
pub fn attr_reset(&mut self) {
self.out(b"\x1B[0m");
}
pub fn full_reset(&mut self) {
self.out(b"\x1Bc");
}
pub fn utf8_mode(&mut self) {
self.out(b"\x1B%G");
}
pub fn scroll_up(&mut self) {
self.to(self.size.0 - 1, 0);
self.out1(10);
}
pub fn save_cleanup(&mut self) {
self.new_cleanup = Some(self.buf.drain(..).collect());
}
pub(crate) fn data_to_flush(&self) -> &[u8] {
&self.buf[..self.flush_to]
}
pub(crate) fn drain_flush(&mut self) {
self.buf.drain(..self.flush_to);
self.flush_to = 0;
}
pub(crate) fn discard(&mut self) {
self.buf.drain(..);
self.flush_to = 0;
}
pub(crate) fn set_size(&mut self, sy: i32, sx: i32) {
self.size = (sy, sx);
}
}
impl Write for TermOut {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.buf.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
pub struct Features {
pub colour_256: bool,
}