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 CHANGEPROG: u8 = 4;
#[derive(Clone, Debug, PartialEq)]
pub struct Msg {
pub sid: u32,
pub program_uid: u32,
pub num_fields: u32,
pub fields: Vec<(Reg, u64)>,
}
impl AsRawMsg for Msg {
fn get_hdr(&self) -> (u8, u32, u32) {
(
CHANGEPROG,
HDR_LENGTH + 4 + 4 + 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, self.program_uid);
w.write_all(&buf[..])?;
u32_to_u8s(&mut buf, 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_changeprog_msg() {
let m = super::Msg {
sid: 1,
program_uid: 7,
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");
#[rustfmt::skip]
assert_eq!(
buf,
vec![
4, 0, 29, 0, 1, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 2, 4, 0, 0, 0, 0x2a, 0, 0, 0, 0, 0, 0, 0, ],
);
}
}