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
|
//! [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)]
|
#[derive(Debug, Builder, Serialize)]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
|
@ -45,8 +50,14 @@ pub struct Theme {
|
||||||
palette: String,
|
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 {
|
pub enum EventKind {
|
||||||
Output(Vec<u8>),
|
Output(Vec<u8>),
|
||||||
Input(Vec<u8>),
|
Input(Vec<u8>),
|
||||||
|
@ -72,3 +83,74 @@ impl Serialize for Event {
|
||||||
seq.end()
|
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