implement deserialize for event

This commit is contained in:
Michael Zhang 2023-02-11 08:49:39 -06:00
parent 99f5f8d9b2
commit 2205d60f62

View file

@ -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<u8>),
Input(Vec<u8>),
@ -72,3 +83,74 @@ impl Serialize for Event {
seq.end()
}
}
impl<'d> Deserialize<'d> for Event {
fn deserialize<D>(de: D) -> std::result::Result<Self, D::Error>
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<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
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<u8> 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);
}