implement deserialize for event
This commit is contained in:
parent
99f5f8d9b2
commit
2205d60f62
1 changed files with 85 additions and 3 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue