Return Reader struct from asciicast::open() instead of an anonymous tuple

This commit is contained in:
Marcin Kulik
2024-01-20 22:35:20 +01:00
parent 21fec08a6a
commit 1b2543f82d
4 changed files with 26 additions and 22 deletions

View File

@@ -17,15 +17,15 @@ impl Cli {
for path in self.filename.iter() {
let reader = io::BufReader::new(fs::File::open(path)?);
let (header, events) = asciicast::open(reader)?;
let recording = asciicast::open(reader)?;
let mut time = time_offset;
if first {
writer.write_header(&header)?;
writer.write_header(&recording.header)?;
first = false;
}
for event in events {
for event in recording.events {
let mut event = event?;
time = time_offset + event.time;
event.time = time;

View File

@@ -1,4 +1,5 @@
use crate::config::Config;
use crate::format::asciicast;
use crate::logger;
use crate::{
player::{self, KeyBindings},
@@ -6,7 +7,6 @@ use crate::{
};
use anyhow::Result;
use clap::Args;
use std::fs;
#[derive(Debug, Args)]
pub struct Cli {
@@ -37,12 +37,12 @@ impl Cli {
logger::info!("Replaying session from {}", self.filename);
let ended = loop {
let file = fs::File::open(&self.filename)?;
let recording = asciicast::open_from_path(&self.filename)?;
let tty = tty::DevTty::open()?;
let keys = get_key_bindings(config)?;
let ended = player::play(
file,
recording,
tty,
speed,
idle_time_limit,

View File

@@ -8,6 +8,11 @@ use std::io::BufRead;
use std::io::{self, Write};
use std::path::Path;
pub struct Reader<'a> {
pub header: Header,
pub events: Box<dyn Iterator<Item = Result<Event>> + 'a>,
}
pub struct Writer<W: Write> {
writer: io::LineWriter<W>,
append: bool,
@@ -96,21 +101,23 @@ where
}
pub fn get_duration<S: AsRef<Path>>(path: S) -> Result<u64> {
let file = fs::File::open(path)?;
let reader = io::BufReader::new(file);
let (_header, events) = open(reader)?;
let Reader { events, .. } = open_from_path(path)?;
let time = events.last().map_or(Ok(0), |e| e.map(|e| e.time))?;
Ok(time)
}
pub fn open<R: BufRead>(reader: R) -> Result<(Header, impl Iterator<Item = Result<Event>>)> {
pub fn open_from_path<S: AsRef<Path>>(path: S) -> Result<Reader<'static>> {
open(io::BufReader::new(fs::File::open(path)?))
}
pub fn open<'a, R: BufRead + 'a>(reader: R) -> Result<Reader<'a>> {
let mut lines = reader.lines();
let first_line = lines.next().ok_or(anyhow::anyhow!("empty file"))??;
let header: Header = serde_json::from_str(&first_line)?;
let events = lines.filter_map(parse_event);
let events = Box::new(lines.filter_map(parse_event));
Ok((header, events))
Ok(Reader { header, events })
}
fn parse_event(line: io::Result<String>) -> Option<Result<Event>> {
@@ -354,7 +361,7 @@ pub fn accelerate(
#[cfg(test)]
mod tests {
use super::{Event, EventCode, Header, Writer};
use super::{Event, EventCode, Header, Reader, Writer};
use anyhow::Result;
use std::collections::HashMap;
use std::fs::File;
@@ -363,7 +370,7 @@ mod tests {
#[test]
fn open() {
let file = File::open("tests/demo.cast").unwrap();
let (header, events) = super::open(io::BufReader::new(file)).unwrap();
let Reader { header, events } = super::open(io::BufReader::new(file)).unwrap();
let events = events.take(7).collect::<Result<Vec<Event>>>().unwrap();

View File

@@ -27,7 +27,7 @@ impl Default for KeyBindings {
}
pub fn play(
recording: impl io::Read,
recording: asciicast::Reader,
mut tty: impl Tty,
speed: f64,
idle_time_limit: Option<f64>,
@@ -128,18 +128,15 @@ pub fn play(
}
fn open_recording(
recording: impl io::Read,
recording: asciicast::Reader<'_>,
speed: f64,
idle_time_limit: Option<f64>,
) -> Result<impl Iterator<Item = Result<Event>>> {
let reader = io::BufReader::new(recording);
let (header, events) = asciicast::open(reader)?;
) -> Result<impl Iterator<Item = Result<Event>> + '_> {
let idle_time_limit = idle_time_limit
.or(header.idle_time_limit)
.or(recording.header.idle_time_limit)
.unwrap_or(f64::MAX);
let events = asciicast::limit_idle_time(events, idle_time_limit);
let events = asciicast::limit_idle_time(recording.events, idle_time_limit);
let events = asciicast::accelerate(events, speed);
Ok(events)