use super::{AsRawMsg, HDR_LENGTH, RawMsg, u32_to_u8s};
use crate::Result;
use crate::lang::Bin;
use std::io::prelude::*;
pub(crate) const INSTALL: u8 = 2;
#[derive(Clone, Debug, PartialEq)]
pub struct Msg {
pub sid: u32,
pub program_uid: u32,
pub num_events: u32,
pub num_instrs: u32,
pub instrs: Bin,
}
impl AsRawMsg for Msg {
fn get_hdr(&self) -> (u8, u32, u32) {
(
INSTALL,
HDR_LENGTH + 12 + (self.num_events * 16 + self.num_instrs * 16),
self.sid,
)
}
fn get_u32s<W: Write>(&self, w: &mut W) -> Result<()> {
let mut buf = [0u8; 4];
u32_to_u8s(&mut buf, self.program_uid);
w.write_all(&buf[..])?;
u32_to_u8s(&mut buf, self.num_events);
w.write_all(&buf[..])?;
u32_to_u8s(&mut buf, self.num_instrs);
w.write_all(&buf[..])?;
Ok(())
}
fn get_bytes<W: Write>(&self, w: &mut W) -> Result<()> {
let buf = self.instrs.serialize()?;
w.write_all(&buf[..])?;
Ok(())
}
fn from_raw_msg(_msg: RawMsg) -> Result<Self> {
unimplemented!();
}
}
#[cfg(test)]
mod tests {
use crate::lang::{Bin, Prog};
#[test]
fn serialize_install_msg() {
let foo = "
(def (Report (volatile foo 0)))
(when true
(bind Report.foo 4)
)
";
let (p, mut sc) = Prog::new_with_scope(foo).unwrap();
let b = Bin::compile_prog(&p, &mut sc).unwrap();
let m = super::Msg {
sid: 1,
program_uid: 7,
num_events: 1,
num_instrs: 3,
instrs: b,
};
let buf: Vec<u8> =
crate::serialize::serialize::<super::Msg>(&m.clone()).expect("serialize");
assert_eq!(
buf,
vec![
2, 0, 84, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0,
0, 2, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4, 0, 0, 0, ],
);
}
}