Refactor Recorder and Writer traits

This commit is contained in:
Marcin Kulik
2024-01-11 11:09:10 +01:00
parent 8479035dc4
commit f6e18c36ad
5 changed files with 65 additions and 60 deletions

View File

@@ -1,4 +1,3 @@
use crate::format;
use crate::format::{asciicast, raw}; use crate::format::{asciicast, raw};
use crate::locale; use crate::locale;
use crate::pty; use crate::pty;
@@ -89,7 +88,7 @@ impl Cli {
.truncate(overwrite) .truncate(overwrite)
.open(&self.filename)?; .open(&self.filename)?;
let writer: Box<dyn format::Writer + Send> = if self.raw { let writer: Box<dyn recorder::EventWriter + Send> = if self.raw {
Box::new(raw::Writer::new(file)) Box::new(raw::Writer::new(file))
} else { } else {
let time_offset = if append { let time_offset = if append {
@@ -105,10 +104,12 @@ impl Cli {
writer, writer,
append, append,
self.stdin, self.stdin,
self.idle_time_limit, recorder::Metadata {
self.command.clone(), idle_time_limit: self.idle_time_limit,
self.title, command: self.command.clone(),
capture_env(&self.env), title: self.title,
env: capture_env(&self.env),
},
); );
let exec_command = build_exec_command(self.command); let exec_command = build_exec_command(self.command);

View File

@@ -1,20 +1,2 @@
pub mod asciicast; pub mod asciicast;
pub mod raw; pub mod raw;
use std::{collections::HashMap, io};
pub trait Writer {
fn header(&mut self, header: &Header) -> io::Result<()>;
fn output(&mut self, time: u64, data: &[u8]) -> io::Result<()>;
fn input(&mut self, time: u64, data: &[u8]) -> io::Result<()>;
fn resize(&mut self, time: u64, size: (u16, u16)) -> io::Result<()>;
}
pub struct Header {
pub cols: u16,
pub rows: u16,
pub timestamp: Option<u64>,
pub idle_time_limit: Option<f64>,
pub command: Option<String>,
pub title: Option<String>,
pub env: HashMap<String, String>,
}

View File

@@ -1,3 +1,4 @@
use crate::recorder;
use anyhow::Result; use anyhow::Result;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::collections::HashMap; use std::collections::HashMap;
@@ -63,12 +64,16 @@ where
} }
} }
impl<W> super::Writer for Writer<W> impl<W> recorder::EventWriter for Writer<W>
where where
W: Write, W: Write,
{ {
fn header(&mut self, header: &super::Header) -> io::Result<()> { fn start(&mut self, header: &recorder::Header, append: bool) -> io::Result<()> {
self.write_header(&header.into()) if append {
Ok(())
} else {
self.write_header(&header.into())
}
} }
fn output(&mut self, time: u64, data: &[u8]) -> io::Result<()> { fn output(&mut self, time: u64, data: &[u8]) -> io::Result<()> {
@@ -267,7 +272,7 @@ fn format_time(time: u64) -> String {
format!("{}.{:0>6}", time / 1_000_000, time % 1_000_000) format!("{}.{:0>6}", time / 1_000_000, time % 1_000_000)
} }
impl From<&Header> for super::Header { impl From<&Header> for recorder::Header {
fn from(header: &Header) -> Self { fn from(header: &Header) -> Self {
Self { Self {
cols: header.width, cols: header.width,
@@ -281,8 +286,8 @@ impl From<&Header> for super::Header {
} }
} }
impl From<&super::Header> for Header { impl From<&recorder::Header> for Header {
fn from(header: &super::Header) -> Self { fn from(header: &recorder::Header) -> Self {
Self { Self {
width: header.cols, width: header.cols,
height: header.rows, height: header.rows,

View File

@@ -1,3 +1,4 @@
use crate::recorder;
use std::io::{self, Write}; use std::io::{self, Write};
pub struct Writer<W> { pub struct Writer<W> {
@@ -10,9 +11,13 @@ impl<W> Writer<W> {
} }
} }
impl<W: Write> super::Writer for Writer<W> { impl<W: Write> recorder::EventWriter for Writer<W> {
fn header(&mut self, header: &super::Header) -> io::Result<()> { fn start(&mut self, header: &recorder::Header, append: bool) -> io::Result<()> {
write!(self.writer, "\x1b[8;{};{}t", header.rows, header.cols) if append {
Ok(())
} else {
write!(self.writer, "\x1b[8;{};{}t", header.rows, header.cols)
}
} }
fn output(&mut self, _time: u64, data: &[u8]) -> io::Result<()> { fn output(&mut self, _time: u64, data: &[u8]) -> io::Result<()> {

View File

@@ -1,4 +1,3 @@
use crate::format;
use crate::pty; use crate::pty;
use std::collections::HashMap; use std::collections::HashMap;
use std::io; use std::io;
@@ -7,19 +6,40 @@ use std::thread;
use std::time::{Instant, SystemTime, UNIX_EPOCH}; use std::time::{Instant, SystemTime, UNIX_EPOCH};
pub struct Recorder { pub struct Recorder {
writer: Option<Box<dyn format::Writer + Send>>, writer: Option<Box<dyn EventWriter + Send>>,
start_time: Instant, start_time: Instant,
append: bool, append: bool,
record_input: bool, record_input: bool,
idle_time_limit: Option<f64>, metadata: Metadata,
command: Option<String>,
title: Option<String>,
env: HashMap<String, String>,
sender: mpsc::Sender<Message>, sender: mpsc::Sender<Message>,
receiver: Option<mpsc::Receiver<Message>>, receiver: Option<mpsc::Receiver<Message>>,
handle: Option<JoinHandle>, handle: Option<JoinHandle>,
} }
pub trait EventWriter {
fn start(&mut self, header: &Header, append: bool) -> io::Result<()>;
fn output(&mut self, time: u64, data: &[u8]) -> io::Result<()>;
fn input(&mut self, time: u64, data: &[u8]) -> io::Result<()>;
fn resize(&mut self, time: u64, size: (u16, u16)) -> io::Result<()>;
}
pub struct Header {
pub cols: u16,
pub rows: u16,
pub timestamp: Option<u64>,
pub idle_time_limit: Option<f64>,
pub command: Option<String>,
pub title: Option<String>,
pub env: HashMap<String, String>,
}
pub struct Metadata {
pub idle_time_limit: Option<f64>,
pub command: Option<String>,
pub title: Option<String>,
pub env: HashMap<String, String>,
}
enum Message { enum Message {
Output(u64, Vec<u8>), Output(u64, Vec<u8>),
Input(u64, Vec<u8>), Input(u64, Vec<u8>),
@@ -30,13 +50,10 @@ struct JoinHandle(Option<thread::JoinHandle<()>>);
impl Recorder { impl Recorder {
pub fn new( pub fn new(
writer: Box<dyn format::Writer + Send>, writer: Box<dyn EventWriter + Send>,
append: bool, append: bool,
record_input: bool, record_input: bool,
idle_time_limit: Option<f64>, metadata: Metadata,
command: Option<String>,
title: Option<String>,
env: HashMap<String, String>,
) -> Self { ) -> Self {
let (sender, receiver) = mpsc::channel(); let (sender, receiver) = mpsc::channel();
@@ -45,10 +62,7 @@ impl Recorder {
start_time: Instant::now(), start_time: Instant::now(),
append, append,
record_input, record_input,
idle_time_limit, metadata,
command,
title,
env,
sender, sender,
receiver: Some(receiver), receiver: Some(receiver),
handle: None, handle: None,
@@ -70,19 +84,17 @@ impl pty::Recorder for Recorder {
let mut writer = self.writer.take().unwrap(); let mut writer = self.writer.take().unwrap();
let receiver = self.receiver.take().unwrap(); let receiver = self.receiver.take().unwrap();
if !self.append { let header = Header {
let header = format::Header { cols: size.0,
cols: size.0, rows: size.1,
rows: size.1, timestamp: Some(timestamp),
timestamp: Some(timestamp), idle_time_limit: self.metadata.idle_time_limit,
idle_time_limit: self.idle_time_limit, command: self.metadata.command.clone(),
command: self.command.clone(), title: self.metadata.title.clone(),
title: self.title.clone(), env: self.metadata.env.clone(),
env: self.env.clone(), };
};
writer.header(&header)?; writer.start(&header, self.append)?;
}
let handle = thread::spawn(move || { let handle = thread::spawn(move || {
for msg in receiver { for msg in receiver {