use super::{AsRawMsg, HDR_LENGTH, RawMsg, u32_to_u8s, u64_to_u8s};
use crate::lang::Reg;
use crate::{Error, Result};
use std::io::prelude::*;
pub(crate) const UPDATE_FIELD: u8 = 3;
#[derive(Clone, Debug, PartialEq)]
pub struct Msg {
pub sid: u32,
pub num_fields: u8,
pub fields: Vec<(Reg, u64)>,
}
impl AsRawMsg for Msg {
fn get_hdr(&self) -> (u8, u32, u32) {
(
UPDATE_FIELD,
HDR_LENGTH + 4 + u32::from(self.num_fields) * 13, self.sid,
)
}
fn get_u32s<W: Write>(&self, w: &mut W) -> Result<()> {
let mut buf = [0u8; 4];
u32_to_u8s(&mut buf, u32::from(self.num_fields));
w.write_all(&buf[..])?;
Ok(())
}
fn get_bytes<W: Write>(&self, w: &mut W) -> Result<()> {
let mut buf = [0u8; 8];
for f in &self.fields {
let reg =
f.0.clone()
.into_iter()
.map(|e| e.map_err(Error::from))
.collect::<Result<Vec<u8>>>()?;
w.write_all(®[..])?;
u64_to_u8s(&mut buf, f.1);
w.write_all(&buf[..])?;
}
Ok(())
}
fn from_raw_msg(_msg: RawMsg) -> Result<Self> {
unimplemented!()
}
}
#[cfg(test)]
mod tests {
use crate::lang::Reg;
#[test]
fn serialize_update_msg() {
let m = super::Msg {
sid: 1,
num_fields: 1,
fields: vec![(Reg::Implicit(4, crate::lang::Type::Num(None)), 42)],
};
let buf: Vec<u8> =
crate::serialize::serialize::<super::Msg>(&m.clone()).expect("serialize");
assert_eq!(
buf,
vec![
3, 0, 25, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 4, 0, 0, 0, 0x2a, 0, 0, 0, 0, 0, 0, 0, ],
);
}
}