use crate::error::{DecodeError, EncodeError};
use crate::request::Encode;
use rusty_modbus_types::{ExceptionCode, FunctionCode};
#[derive(Debug, Clone, Copy)]
pub struct ExceptionResponse {
pub function_code: FunctionCode,
pub exception_code: ExceptionCode,
}
impl ExceptionResponse {
pub fn decode(fc_byte: u8, data: &[u8]) -> Result<Self, DecodeError> {
DecodeError::check_exact_len(data, 1)?;
let raw_function_code = fc_byte & 0x7F;
if raw_function_code == 0 {
return Err(DecodeError::UnknownFunctionCode(raw_function_code));
}
let function_code = FunctionCode::from_exception_raw(fc_byte);
let exception_code = ExceptionCode::from_raw(data[0]);
Ok(Self {
function_code,
exception_code,
})
}
}
impl Encode for ExceptionResponse {
fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
let len = self.encoded_len();
if buf.len() < len {
return Err(EncodeError::BufferTooSmall {
required: len,
available: buf.len(),
});
}
EncodeError::check_pdu_len(len)?;
buf[0] = self.function_code.exception_code();
buf[1] = self.exception_code.code();
Ok(len)
}
fn encoded_len(&self) -> usize {
2
}
}