rusty_modbus_codec/response/
fifo.rs1use crate::error::{DecodeError, EncodeError};
4use crate::request::Encode;
5use rusty_modbus_types::{FunctionCode, MAX_FIFO_VALUES};
6
7#[derive(Debug)]
9pub struct ReadFifoQueueResponse<'buf> {
10 pub byte_count: u16,
12 pub fifo_count: u16,
14 pub fifo_values: &'buf [u8],
16}
17
18impl<'buf> ReadFifoQueueResponse<'buf> {
19 pub fn decode(data: &'buf [u8]) -> Result<Self, DecodeError> {
27 if data.len() < 4 {
28 return Err(DecodeError::Truncated {
29 expected: 4,
30 actual: data.len(),
31 });
32 }
33 let byte_count = u16::from_be_bytes([data[0], data[1]]);
34 let fifo_count = u16::from_be_bytes([data[2], data[3]]);
35 let fifo_values = &data[4..];
36 if byte_count < 2 {
39 return Err(DecodeError::ByteCountMismatch {
40 declared: usize::from(byte_count),
41 actual: 2 + fifo_values.len(),
42 });
43 }
44 let expected_remaining = usize::from(byte_count) - 2;
45 if fifo_values.len() != expected_remaining {
46 return Err(DecodeError::ByteCountMismatch {
47 declared: expected_remaining,
48 actual: fifo_values.len(),
49 });
50 }
51 if fifo_count > 31 {
53 return Err(DecodeError::QuantityOutOfRange {
54 quantity: fifo_count,
55 });
56 }
57 let expected_data_len = usize::from(fifo_count) * 2;
59 if fifo_values.len() != expected_data_len {
60 return Err(DecodeError::ByteCountMismatch {
61 declared: expected_data_len,
62 actual: fifo_values.len(),
63 });
64 }
65 Ok(Self {
66 byte_count,
67 fifo_count,
68 fifo_values,
69 })
70 }
71}
72
73impl Encode for ReadFifoQueueResponse<'_> {
74 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
75 let len = self.encoded_len();
76 if buf.len() < len {
77 return Err(EncodeError::BufferTooSmall {
78 required: len,
79 available: buf.len(),
80 });
81 }
82 EncodeError::check_byte_count(usize::from(self.byte_count), 2 + self.fifo_values.len())?;
83 if self.fifo_count > MAX_FIFO_VALUES {
84 return Err(EncodeError::QuantityOutOfRange {
85 quantity: self.fifo_count,
86 });
87 }
88 let expected_data_len = usize::from(self.fifo_count) * 2;
89 EncodeError::check_byte_count(expected_data_len, self.fifo_values.len())?;
90 EncodeError::check_pdu_len(len)?;
91 buf[0] = FunctionCode::ReadFifoQueue.code();
92 let bc = self.byte_count.to_be_bytes();
93 buf[1] = bc[0];
94 buf[2] = bc[1];
95 let fc = self.fifo_count.to_be_bytes();
96 buf[3] = fc[0];
97 buf[4] = fc[1];
98 buf[5..5 + self.fifo_values.len()].copy_from_slice(self.fifo_values);
99 Ok(len)
100 }
101
102 fn encoded_len(&self) -> usize {
103 1 + 2 + 2 + self.fifo_values.len()
105 }
106}