use std::io::BufRead;
use serde::Deserialize;
use crate::{
Asciicast, Error,
versions::{V1, Version, common::Env},
};
pub type Recording = Asciicast<V1>;
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Header {
pub version: u8,
pub width: u16,
pub height: u16,
pub duration: f64,
#[serde(default)]
pub command: Option<String>,
#[serde(default)]
pub title: Option<String>,
#[serde(default)]
pub env: Option<Env>,
}
#[derive(Deserialize)]
struct RawFrame(f64, String);
#[derive(Debug, Clone, PartialEq)]
pub struct Frame {
pub delay: f64,
pub data: String,
}
impl From<RawFrame> for Frame {
fn from(raw: RawFrame) -> Self {
let RawFrame(delay, data) = raw;
Self { delay, data }
}
}
#[derive(Deserialize)]
struct Document {
#[serde(flatten)]
header: Header,
stdout: Vec<RawFrame>,
}
pub(crate) fn parse<R: BufRead>(reader: R) -> Result<Asciicast<V1>, Error> {
let document: Document = serde_json::from_reader(reader)?;
if document.header.version != V1::NUMBER {
return Err(Error::VersionMismatch {
expected: V1::NUMBER,
found: document.header.version,
});
}
let events = document.stdout.into_iter().map(Frame::from).collect();
Ok(Asciicast {
header: document.header,
events,
})
}