use alloc::vec::Vec;
use core::fmt::Debug;
use binrw::{BinRead, BinWrite};
use bon::bon;
use crate::protocol;
#[must_use]
#[derive(Clone, Debug, BinWrite)]
#[bw(big)]
pub struct Args {
starting_address: u16,
n_registers: u16,
n_bytes: u8,
words: Vec<u16>,
}
#[bon]
impl Args {
#[builder]
pub fn new(
starting_address: u16,
words: Vec<u16>,
) -> Result<Self, protocol::Error> {
let n_registers = words.len();
if (1..=123).contains(&n_registers) {
let n_registers = u16::try_from(n_registers).unwrap();
let n_bytes = u8::try_from(n_registers * 2).unwrap();
Ok(Self { starting_address, n_registers, n_bytes, words })
} else {
Err(protocol::Error::InvalidCount(n_registers))
}
}
}
#[must_use]
#[derive(Copy, Clone, derive_more::Debug, BinRead)]
#[br(big)]
pub struct Output {
pub starting_address: u16,
pub n_registers: u16,
}
#[cfg(test)]
mod tests {
use alloc::vec;
use binrw::{BinRead, io::Cursor};
use super::*;
#[test]
fn request_example_ok() {
const EXPECTED: &[u8] = &[
0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x0A, 0x01, 0x02, ];
let mut output = Cursor::new(vec![]);
Args::builder()
.starting_address(1)
.words(vec![0x000A, 0x0102])
.build()
.unwrap()
.write(&mut output)
.unwrap();
assert_eq!(output.into_inner(), EXPECTED);
}
#[test]
fn response_example_ok() {
const RESPONSE: &[u8] = &[
0x00, 0x01, 0x00, 0x02, ];
let response = Output::read(&mut Cursor::new(RESPONSE)).unwrap();
assert_eq!(response.starting_address, 1);
assert_eq!(response.n_registers, 2);
}
}