Skip to main content

write_cast

Function write_cast 

Source
pub fn write_cast(
    writer: &mut impl Write,
    size: Size,
    frames: &[CapturedFrame],
) -> Result<()>
Expand description

Exports frames as asciicast v3 newline-delimited JSON, written to writer.

frames comes from FrameRecorder or the pty feature’s capture source. Writes a header line ({"version": 3, "term": {"cols", "rows"}}) sized to size, then one [interval_seconds, "o", ansi_text] event line per captured frame: interval_seconds is the time since the previous event (since FrameRecorder::new for the first), and ansi_text repositions the cursor to each changed cell (\x1b[{row};{col}H, grouping horizontally-adjacent runs to avoid a move per cell) and writes its glyph, switching SGR state only when the style actually changes – exactly what a real terminal session emitting that frame would have sent, and exactly what an asciicast player (asciinema-player) or converter (agg, svg-term) expects to replay.

Hand-rolled (via serde_json, not the asciicast/asciicast-rs crates) because this crate only ever writes v3, never parses any version – a parser’s surface would be pure dead weight here.

No timestamp header field is emitted: it would be wall-clock-dependent, and this exists for deterministic, insta-snapshottable captures.

§Known limitation

Buffers and serializes every frame at once rather than streaming events to writer as they’re captured, so a session’s full cost (memory in FrameRecorder, then this function’s formatting work) is paid up front. Matches FrameRecorder’s own whole-session-in-memory limitation; fine for docs/demo-length captures.

§Errors

Returns an error if writer fails to write.

§Examples

use retroglyph_core::backend::{DrawCell, Headless, Output};
use retroglyph_core::color::Style;
use retroglyph_core::grid::Pos;
use retroglyph_core::tile::Tile;
use retroglyph_recorder::{write_cast, FrameRecorder};

let mut recorder = FrameRecorder::new(Headless::new(3, 1));
let tile = Tile::new('a', Style::default());
recorder
    .draw_layers(std::iter::once(DrawCell::new(Pos::new(0, 0), &tile)))
    .unwrap();

let mut out = Vec::new();
write_cast(&mut out, recorder.inner().size(), &recorder.frames()).unwrap();
let text = String::from_utf8(out).unwrap();
assert!(text.contains("\"version\":3"));
assert!(text.contains("\"o\""));