Refactor ALiS event serialization

This commit is contained in:
Marcin Kulik
2025-05-29 21:18:01 +02:00
parent 31cc393efe
commit 1c0bcdd4c2

View File

@@ -15,140 +15,150 @@ use crate::stream::Event;
static MAGIC_STRING: &str = "ALiS\x01"; static MAGIC_STRING: &str = "ALiS\x01";
struct EventSerializer(u64);
pub async fn stream<S: Stream<Item = Result<Event, BroadcastStreamRecvError>>>( pub async fn stream<S: Stream<Item = Result<Event, BroadcastStreamRecvError>>>(
stream: S, stream: S,
) -> Result<impl Stream<Item = Result<Vec<u8>, BroadcastStreamRecvError>>> { ) -> Result<impl Stream<Item = Result<Vec<u8>, BroadcastStreamRecvError>>> {
let header = stream::once(future::ready(Ok(MAGIC_STRING.into()))); let header = stream::once(future::ready(Ok(MAGIC_STRING.into())));
let mut serializer = EventSerializer(0);
let events = stream.scan(0u64, |prev_event_time, event| { let events = stream.map(move |event| event.map(|event| serializer.serialize_event(event)));
future::ready(Some(event.map(|event| {
let (bytes, time) = serialize_event(event, *prev_event_time);
*prev_event_time = time;
bytes
})))
});
Ok(header.chain(events)) Ok(header.chain(events))
} }
fn serialize_event(event: Event, prev_event_time: u64) -> (Vec<u8>, u64) { impl EventSerializer {
use Event::*; fn serialize_event(&mut self, event: Event) -> Vec<u8> {
use Event::*;
match event { match event {
Init(last_id, time, size, theme, init) => { Init(last_id, time, size, theme, init) => {
let last_id_bytes = leb128::encode(last_id); let last_id_bytes = leb128::encode(last_id);
let time_bytes = leb128::encode(time); let time_bytes = leb128::encode(time);
let cols_bytes = leb128::encode(size.0); let cols_bytes = leb128::encode(size.0);
let rows_bytes = leb128::encode(size.1); let rows_bytes = leb128::encode(size.1);
let init_len = init.len() as u32; let init_len = init.len() as u32;
let init_len_bytes = leb128::encode(init_len); let init_len_bytes = leb128::encode(init_len);
let mut msg = vec![0x01]; let mut msg = vec![0x01];
msg.extend_from_slice(&last_id_bytes); msg.extend_from_slice(&last_id_bytes);
msg.extend_from_slice(&time_bytes); msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&cols_bytes); msg.extend_from_slice(&cols_bytes);
msg.extend_from_slice(&rows_bytes); msg.extend_from_slice(&rows_bytes);
match theme { match theme {
Some(theme) => { Some(theme) => {
msg.push(16); msg.push(16);
msg.push(theme.fg.r); msg.push(theme.fg.r);
msg.push(theme.fg.g); msg.push(theme.fg.g);
msg.push(theme.fg.b); msg.push(theme.fg.b);
msg.push(theme.bg.r); msg.push(theme.bg.r);
msg.push(theme.bg.g); msg.push(theme.bg.g);
msg.push(theme.bg.b); msg.push(theme.bg.b);
for color in &theme.palette { for color in &theme.palette {
msg.push(color.r); msg.push(color.r);
msg.push(color.g); msg.push(color.g);
msg.push(color.b); msg.push(color.b);
}
}
None => {
msg.push(0);
} }
} }
None => { msg.extend_from_slice(&init_len_bytes);
msg.push(0); msg.extend_from_slice(init.as_bytes());
}
self.0 = time;
msg
} }
msg.extend_from_slice(&init_len_bytes); Output(id, time, text) => {
msg.extend_from_slice(init.as_bytes()); let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - self.0);
let text_len = text.len() as u32;
let text_len_bytes = leb128::encode(text_len);
(msg, time) let mut msg = vec![b'o'];
} msg.extend_from_slice(&id_bytes);
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&text_len_bytes);
msg.extend_from_slice(text.as_bytes());
Output(id, time, text) => { self.0 = time;
let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - prev_event_time);
let text_len = text.len() as u32;
let text_len_bytes = leb128::encode(text_len);
let mut msg = vec![b'o']; msg
msg.extend_from_slice(&id_bytes); }
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&text_len_bytes);
msg.extend_from_slice(text.as_bytes());
(msg, time) Input(id, time, text) => {
} let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - self.0);
let text_len = text.len() as u32;
let text_len_bytes = leb128::encode(text_len);
Input(id, time, text) => { let mut msg = vec![b'i'];
let id_bytes = leb128::encode(id); msg.extend_from_slice(&id_bytes);
let time_bytes = leb128::encode(time - prev_event_time); msg.extend_from_slice(&time_bytes);
let text_len = text.len() as u32; msg.extend_from_slice(&text_len_bytes);
let text_len_bytes = leb128::encode(text_len); msg.extend_from_slice(text.as_bytes());
let mut msg = vec![b'i']; self.0 = time;
msg.extend_from_slice(&id_bytes);
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&text_len_bytes);
msg.extend_from_slice(text.as_bytes());
(msg, time) msg
} }
Resize(id, time, size) => { Resize(id, time, size) => {
let id_bytes = leb128::encode(id); let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - prev_event_time); let time_bytes = leb128::encode(time - self.0);
let cols_bytes = leb128::encode(size.0); let cols_bytes = leb128::encode(size.0);
let rows_bytes = leb128::encode(size.1); let rows_bytes = leb128::encode(size.1);
let mut msg = vec![b'r']; let mut msg = vec![b'r'];
msg.extend_from_slice(&id_bytes); msg.extend_from_slice(&id_bytes);
msg.extend_from_slice(&time_bytes); msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&cols_bytes); msg.extend_from_slice(&cols_bytes);
msg.extend_from_slice(&rows_bytes); msg.extend_from_slice(&rows_bytes);
(msg, time) self.0 = time;
}
Marker(id, time, text) => { msg
let id_bytes = leb128::encode(id); }
let time_bytes = leb128::encode(time - prev_event_time);
let text_len = text.len() as u32;
let text_len_bytes = leb128::encode(text_len);
let mut msg = vec![b'm']; Marker(id, time, text) => {
msg.extend_from_slice(&id_bytes); let id_bytes = leb128::encode(id);
msg.extend_from_slice(&time_bytes); let time_bytes = leb128::encode(time - self.0);
msg.extend_from_slice(&text_len_bytes); let text_len = text.len() as u32;
msg.extend_from_slice(text.as_bytes()); let text_len_bytes = leb128::encode(text_len);
(msg, time) let mut msg = vec![b'm'];
} msg.extend_from_slice(&id_bytes);
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&text_len_bytes);
msg.extend_from_slice(text.as_bytes());
Exit(id, time, status) => { self.0 = time;
let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - prev_event_time);
let status_bytes = leb128::encode(status.max(0) as u64);
let mut msg = vec![b'x']; msg
msg.extend_from_slice(&id_bytes); }
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&status_bytes);
(msg, time) Exit(id, time, status) => {
let id_bytes = leb128::encode(id);
let time_bytes = leb128::encode(time - self.0);
let status_bytes = leb128::encode(status.max(0) as u64);
let mut msg = vec![b'x'];
msg.extend_from_slice(&id_bytes);
msg.extend_from_slice(&time_bytes);
msg.extend_from_slice(&status_bytes);
self.0 = time;
msg
}
} }
} }
} }