use std::fmt::{Display, Formatter};
mod constants {
pub(crate) const READ_COILS: u8 = 1;
pub(crate) const READ_DISCRETE_INPUTS: u8 = 2;
pub(crate) const READ_HOLDING_REGISTERS: u8 = 3;
pub(crate) const READ_INPUT_REGISTERS: u8 = 4;
pub(crate) const WRITE_SINGLE_COIL: u8 = 5;
pub(crate) const WRITE_SINGLE_REGISTER: u8 = 6;
pub(crate) const WRITE_MULTIPLE_COILS: u8 = 15;
pub(crate) const WRITE_MULTIPLE_REGISTERS: u8 = 16;
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(u8)]
pub(crate) enum FunctionCode {
ReadCoils = constants::READ_COILS,
ReadDiscreteInputs = constants::READ_DISCRETE_INPUTS,
ReadHoldingRegisters = constants::READ_HOLDING_REGISTERS,
ReadInputRegisters = constants::READ_INPUT_REGISTERS,
WriteSingleCoil = constants::WRITE_SINGLE_COIL,
WriteSingleRegister = constants::WRITE_SINGLE_REGISTER,
WriteMultipleCoils = constants::WRITE_MULTIPLE_COILS,
WriteMultipleRegisters = constants::WRITE_MULTIPLE_REGISTERS,
}
impl Display for FunctionCode {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
FunctionCode::ReadCoils => write!(f, "READ COILS ({:#04X})", self.get_value()),
FunctionCode::ReadDiscreteInputs => {
write!(f, "READ DISCRETE INPUTS ({:#04X})", self.get_value())
}
FunctionCode::ReadHoldingRegisters => {
write!(f, "READ HOLDING REGISTERS ({:#04X})", self.get_value())
}
FunctionCode::ReadInputRegisters => {
write!(f, "READ INPUT REGISTERS ({:#04X})", self.get_value())
}
FunctionCode::WriteSingleCoil => {
write!(f, "WRITE SINGLE COIL ({:#04X})", self.get_value())
}
FunctionCode::WriteSingleRegister => {
write!(f, "WRITE SINGLE REGISTER ({:#04X})", self.get_value())
}
FunctionCode::WriteMultipleCoils => {
write!(f, "WRITE MULTIPLE COILS ({:#04X})", self.get_value())
}
FunctionCode::WriteMultipleRegisters => {
write!(f, "WRITE MULTIPLE REGISTERS ({:#04X})", self.get_value())
}
}
}
}
impl FunctionCode {
pub(crate) const fn get_value(self) -> u8 {
self as u8
}
pub(crate) const fn as_error(self) -> u8 {
self.get_value() | 0x80
}
pub(crate) fn get(value: u8) -> Option<Self> {
match value {
constants::READ_COILS => Some(FunctionCode::ReadCoils),
constants::READ_DISCRETE_INPUTS => Some(FunctionCode::ReadDiscreteInputs),
constants::READ_HOLDING_REGISTERS => Some(FunctionCode::ReadHoldingRegisters),
constants::READ_INPUT_REGISTERS => Some(FunctionCode::ReadInputRegisters),
constants::WRITE_SINGLE_COIL => Some(FunctionCode::WriteSingleCoil),
constants::WRITE_SINGLE_REGISTER => Some(FunctionCode::WriteSingleRegister),
constants::WRITE_MULTIPLE_COILS => Some(FunctionCode::WriteMultipleCoils),
constants::WRITE_MULTIPLE_REGISTERS => Some(FunctionCode::WriteMultipleRegisters),
_ => None,
}
}
}