From 2205d60f6218dbc8791828465bfeb7085cd8d897 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sat, 11 Feb 2023 08:49:39 -0600 Subject: [PATCH] implement deserialize for event --- src/asciicast.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/src/asciicast.rs b/src/asciicast.rs index 9e96eac..82ab069 100644 --- a/src/asciicast.rs +++ b/src/asciicast.rs @@ -2,9 +2,14 @@ //! //! [asciicast v2]: https://github.com/asciinema/asciinema/blob/develop/doc/asciicast-v2.md -use std::collections::HashMap; +use std::{collections::HashMap, fmt}; -use serde::ser::{Serialize, SerializeSeq, Serializer}; +use serde::{ + de::{ + Deserialize, Deserializer, Error as DeError, SeqAccess, Unexpected, Visitor, + }, + ser::{Serialize, SerializeSeq, Serializer}, +}; #[derive(Debug, Builder, Serialize)] pub struct Header { @@ -45,8 +50,14 @@ pub struct Theme { palette: String, } -pub struct Event(pub f64, pub EventKind); +#[derive(Debug, Clone, PartialEq)] +pub struct Event( + /// Elapsed time + pub f64, + pub EventKind, +); +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum EventKind { Output(Vec), Input(Vec), @@ -72,3 +83,74 @@ impl Serialize for Event { seq.end() } } + +impl<'d> Deserialize<'d> for Event { + fn deserialize(de: D) -> std::result::Result + where + D: Deserializer<'d>, + { + struct Vis; + impl<'de> Visitor<'de> for Vis { + type Value = Event; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("an array of [timestamp, o or i, data]") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let elapsed: f64 = match seq.next_element()? { + Some(v) => v, + None => { + return Err(A::Error::invalid_length(0, &"an array of length 3")) + } + }; + + let io: char = match seq.next_element()? { + Some(v) => v, + None => { + return Err(A::Error::invalid_length(1, &"an array of length 3")) + } + }; + + // Must first go through &[u8] then to Vec because serde_json treats + // &[u8] specially when it comes to deserializing from binary strings + let data = { + let data: &'de [u8] = match seq.next_element()? { + Some(v) => v, + None => { + return Err(A::Error::invalid_length(2, &"an array of length 3")) + } + }; + data.to_vec() + }; + + let event_kind = match io { + 'i' => EventKind::Input(data), + 'o' => EventKind::Output(data), + _ => { + return Err(A::Error::invalid_value( + Unexpected::Char(io), + &"either i or o", + )) + } + }; + + Ok(Event(elapsed, event_kind)) + } + } + + de.deserialize_seq(Vis) + } +} + +#[test] +fn test() { + let evt = Event(1.5, EventKind::Output(vec![69, 42])); + let evt_ser = serde_json::to_string(&evt).unwrap(); + eprintln!("ser: {evt_ser}"); + let evt_de: Event = serde_json::from_str(&evt_ser).unwrap(); + assert_eq!(evt, evt_de); +}