Use avt's TextCollector to make TextEncoder incremental

This commit is contained in:
Marcin Kulik
2024-01-28 18:23:07 +01:00
parent 6f86c64371
commit b834a100cb
6 changed files with 36 additions and 39 deletions

4
Cargo.lock generated
View File

@@ -135,8 +135,8 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "avt"
version = "0.8.3"
source = "git+https://github.com/asciinema/avt?tag=v0.8.3#28aed2b5a65a4ff07344fd6bc51b8ccb8542389c"
version = "0.9.0"
source = "git+https://github.com/asciinema/avt?tag=v0.9.0#4e086767d775b149f3fb92bae9b5d94a96f9b358"
dependencies = [
"rgb",
"serde",

View File

@@ -25,4 +25,4 @@ config = { version = "0.13.4", default-features = false, features = ["toml", "in
which = "5.0.0"
tempfile = "3.9.0"
scraper = { version = "0.15.0", default-features = false }
avt = { git = "https://github.com/asciinema/avt", tag = "v0.8.3" }
avt = { git = "https://github.com/asciinema/avt", tag = "v0.9.0" }

View File

@@ -60,7 +60,7 @@ impl Cli {
))),
Format::Raw => Ok(Box::new(encoder::RawEncoder::new(file, false))),
Format::Txt => Ok(Box::new(encoder::TxtEncoder::new(file))),
Format::Txt => Ok(Box::new(encoder::TextEncoder::new(file))),
}
}

View File

@@ -189,7 +189,7 @@ impl Cli {
}
Format::Raw => Ok(Box::new(encoder::RawEncoder::new(file, append))),
Format::Txt => Ok(Box::new(encoder::TxtEncoder::new(file))),
Format::Txt => Ok(Box::new(encoder::TextEncoder::new(file))),
}
}

View File

@@ -5,7 +5,7 @@ mod txt;
pub use asciicast::AsciicastEncoder;
pub use asciicast::Metadata;
pub use raw::RawEncoder;
pub use txt::TxtEncoder;
pub use txt::TextEncoder;
use crate::asciicast::Event;
use crate::recorder;

View File

@@ -1,70 +1,67 @@
use crate::asciicast::{Event, EventData};
use crate::tty;
use avt::util::{TextCollector, TextCollectorOutput};
use std::io::{self, Write};
pub struct TxtEncoder<W> {
writer: W,
vt: Option<avt::Vt>,
pub struct TextEncoder<W: Write> {
writer: Option<W>,
collector: Option<TextCollector<TextWriter<W>>>,
}
impl<W> TxtEncoder<W> {
impl<W: Write> TextEncoder<W> {
pub fn new(writer: W) -> Self {
TxtEncoder { writer, vt: None }
TextEncoder {
writer: Some(writer),
collector: None,
}
}
}
impl<W: Write> super::Encoder for TxtEncoder<W> {
impl<W: Write> super::Encoder for TextEncoder<W> {
fn start(&mut self, _timestamp: Option<u64>, tty_size: &tty::TtySize) -> io::Result<()> {
let vt = avt::Vt::builder()
.size(tty_size.0 as usize, tty_size.1 as usize)
.resizable(true)
.scrollback_limit(100)
.build();
self.vt = Some(vt);
self.collector = Some(TextCollector::new(
vt,
TextWriter(self.writer.take().unwrap()),
));
Ok(())
}
fn event(&mut self, event: &Event) -> io::Result<()> {
use EventData::*;
match &event.data {
EventData::Output(data) => {
self.vt.as_mut().unwrap().feed_str(data);
Ok(())
}
EventData::Resize(cols, rows) => {
self.vt
.as_mut()
.unwrap()
.feed_str(&format!("\x1b[8;{rows};{cols}t"));
Ok(())
}
Output(data) => self.collector.as_mut().unwrap().feed_str(data),
Resize(cols, rows) => self.collector.as_mut().unwrap().resize(*cols, *rows),
_ => Ok(()),
}
}
fn finish(&mut self) -> io::Result<()> {
let mut text = self.vt.as_ref().unwrap().text();
self.collector.as_mut().unwrap().flush()
}
}
while !text.is_empty() && text[text.len() - 1].is_empty() {
text.truncate(text.len() - 1);
}
struct TextWriter<W: Write>(W);
for line in text {
self.writer.write_all(line.as_bytes())?;
self.writer.write_all(b"\n")?;
}
impl<W: Write> TextCollectorOutput for TextWriter<W> {
type Error = io::Error;
Ok(())
fn push(&mut self, line: String) -> Result<(), Self::Error> {
self.0.write_all(line.as_bytes())?;
self.0.write_all(b"\n")
}
}
#[cfg(test)]
mod test {
use super::TxtEncoder;
use super::TextEncoder;
use crate::asciicast::Event;
use crate::encoder::Encoder;
use crate::tty::TtySize;
@@ -72,7 +69,7 @@ mod test {
#[test]
fn encoder_impl() {
let mut out: Vec<u8> = Vec::new();
let mut enc = TxtEncoder::new(&mut out);
let mut enc = TextEncoder::new(&mut out);
enc.start(None, &TtySize(3, 1)).unwrap();
enc.event(&Event::output(0, b"he\x1b[1mllo\r\n")).unwrap();