use alloc::{boxed::Box, vec::Vec};
use core::fmt::Debug;
use binrw::{BinRead, BinWrite, binwrite};
use bon::bon;
use crate::protocol;
#[must_use]
#[derive(Copy, Clone, Debug, BinWrite)]
#[bw(big)]
pub struct Args {
starting_address: u16,
n_registers: u16,
}
#[bon]
impl Args {
#[builder]
pub fn new(
starting_address: u16,
n_registers: u16,
) -> Result<Self, protocol::Error> {
if (1..=125).contains(&n_registers) {
Ok(Self { starting_address, n_registers })
} else {
Err(protocol::Error::InvalidCount(n_registers.into()))
}
}
}
#[must_use]
#[binwrite]
#[derive(Copy, Clone, Debug)]
#[bw(big)]
pub struct ArgsExact<const N: usize> {
starting_address: u16,
#[bw(try_calc = u16::try_from(N))]
n_registers: u16,
}
impl<const N: usize> ArgsExact<N> {
pub const fn new(starting_address: u16) -> Self {
Self { starting_address }
}
}
#[must_use]
#[derive(Clone, derive_more::Debug, BinRead)]
#[br(big)]
pub struct Output {
pub n_bytes: u8,
#[br(assert(n_bytes.is_multiple_of(2)), count = n_bytes / 2)]
pub words: Vec<u16>,
}
#[must_use]
#[derive(Clone, derive_more::Debug, BinRead)]
#[br(big)]
pub struct OutputExact<const N: usize> {
#[br(assert(usize::from(n_bytes) == 2 * N))]
pub n_bytes: u8,
pub words: [u16; N],
}