use crate::errors::MbusError;
pub const MAX_REGISTERS_PER_PDU: usize = 125;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Registers<const N: usize = MAX_REGISTERS_PER_PDU> {
from_address: u16,
quantity: u16,
values: [u16; N],
}
impl<const N: usize> Registers<N> {
pub fn new(from_address: u16, quantity: u16) -> Result<Self, MbusError> {
if quantity as usize > N {
return Err(MbusError::InvalidQuantity);
}
Ok(Self {
from_address,
quantity,
values: [0; N],
})
}
pub fn with_values(mut self, values: &[u16], length: u16) -> Result<Self, MbusError> {
if length > N as u16 {
return Err(MbusError::InvalidQuantity);
}
if length > self.quantity {
return Err(MbusError::InvalidQuantity);
}
self.values[..length as usize].copy_from_slice(values);
Ok(self)
}
pub fn from_address(&self) -> u16 {
self.from_address
}
pub fn quantity(&self) -> u16 {
self.quantity
}
pub fn values(&self) -> &[u16; N] {
&self.values
}
pub fn set_value(&mut self, address: u16, value: u16) -> Result<(), MbusError> {
if address < self.from_address || address >= self.from_address + self.quantity {
return Err(MbusError::InvalidAddress);
}
let index = (address - self.from_address) as usize;
self.values[index] = value;
Ok(())
}
pub fn value(&self, address: u16) -> Result<u16, MbusError> {
if address < self.from_address || address >= self.from_address + self.quantity {
return Err(MbusError::InvalidAddress);
}
let index = (address - self.from_address) as usize;
self.values
.get(index)
.copied()
.ok_or(MbusError::InvalidAddress)
}
}