rusty_modbus_codec/response/
reg_write.rs1use crate::error::{DecodeError, EncodeError};
4use crate::request::Encode;
5use rusty_modbus_types::{Address, FunctionCode, MAX_WRITE_REGISTERS, Quantity};
6
7#[derive(Debug)]
11pub struct WriteSingleRegisterResponse {
12 pub address: Address,
14 pub value: u16,
16}
17
18impl WriteSingleRegisterResponse {
19 pub fn decode(data: &[u8]) -> Result<Self, DecodeError> {
26 DecodeError::check_exact_len(data, 4)?;
27 let address = Address(u16::from_be_bytes([data[0], data[1]]));
28 let value = u16::from_be_bytes([data[2], data[3]]);
29 Ok(Self { address, value })
30 }
31}
32
33impl Encode for WriteSingleRegisterResponse {
34 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
35 let len = self.encoded_len();
36 if buf.len() < len {
37 return Err(EncodeError::BufferTooSmall {
38 required: len,
39 available: buf.len(),
40 });
41 }
42 EncodeError::check_pdu_len(len)?;
43 buf[0] = FunctionCode::WriteSingleRegister.code();
44 let addr = self.address.0.to_be_bytes();
45 buf[1] = addr[0];
46 buf[2] = addr[1];
47 let val = self.value.to_be_bytes();
48 buf[3] = val[0];
49 buf[4] = val[1];
50 Ok(len)
51 }
52
53 fn encoded_len(&self) -> usize {
54 1 + 4
55 }
56}
57
58#[derive(Debug)]
60pub struct WriteMultipleRegistersResponse {
61 pub address: Address,
63 pub quantity: Quantity,
65}
66
67impl WriteMultipleRegistersResponse {
68 pub fn decode(data: &[u8]) -> Result<Self, DecodeError> {
75 DecodeError::check_exact_len(data, 4)?;
76 let address = Address(u16::from_be_bytes([data[0], data[1]]));
77 let quantity = Quantity(u16::from_be_bytes([data[2], data[3]]));
78 Ok(Self { address, quantity })
79 }
80}
81
82impl Encode for WriteMultipleRegistersResponse {
83 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
84 let len = self.encoded_len();
85 if buf.len() < len {
86 return Err(EncodeError::BufferTooSmall {
87 required: len,
88 available: buf.len(),
89 });
90 }
91 EncodeError::check_quantity(self.quantity.0, MAX_WRITE_REGISTERS)?;
92 EncodeError::check_pdu_len(len)?;
93 buf[0] = FunctionCode::WriteMultipleRegisters.code();
94 let addr = self.address.0.to_be_bytes();
95 buf[1] = addr[0];
96 buf[2] = addr[1];
97 let qty = self.quantity.0.to_be_bytes();
98 buf[3] = qty[0];
99 buf[4] = qty[1];
100 Ok(len)
101 }
102
103 fn encoded_len(&self) -> usize {
104 1 + 4
105 }
106}
107
108#[derive(Debug)]
112pub struct MaskWriteRegisterResponse {
113 pub address: Address,
115 pub and_mask: u16,
117 pub or_mask: u16,
119}
120
121impl MaskWriteRegisterResponse {
122 pub fn decode(data: &[u8]) -> Result<Self, DecodeError> {
129 DecodeError::check_exact_len(data, 6)?;
130 let address = Address(u16::from_be_bytes([data[0], data[1]]));
131 let and_mask = u16::from_be_bytes([data[2], data[3]]);
132 let or_mask = u16::from_be_bytes([data[4], data[5]]);
133 Ok(Self {
134 address,
135 and_mask,
136 or_mask,
137 })
138 }
139}
140
141impl Encode for MaskWriteRegisterResponse {
142 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
143 let len = self.encoded_len();
144 if buf.len() < len {
145 return Err(EncodeError::BufferTooSmall {
146 required: len,
147 available: buf.len(),
148 });
149 }
150 EncodeError::check_pdu_len(len)?;
151 buf[0] = FunctionCode::MaskWriteRegister.code();
152 let addr = self.address.0.to_be_bytes();
153 buf[1] = addr[0];
154 buf[2] = addr[1];
155 let and_m = self.and_mask.to_be_bytes();
156 buf[3] = and_m[0];
157 buf[4] = and_m[1];
158 let or_m = self.or_mask.to_be_bytes();
159 buf[5] = or_m[0];
160 buf[6] = or_m[1];
161 Ok(len)
162 }
163
164 fn encoded_len(&self) -> usize {
165 1 + 6
166 }
167}
168
169#[derive(Debug)]
171pub struct ReadWriteMultipleRegistersResponse<'buf> {
172 pub byte_count: u8,
174 pub register_data: &'buf [u8],
176}
177
178impl<'buf> ReadWriteMultipleRegistersResponse<'buf> {
179 #[must_use]
181 pub fn count(&self) -> usize {
182 self.register_data.len() / 2
183 }
184
185 #[must_use]
191 pub fn register(&self, index: usize) -> u16 {
192 let off = index * 2;
193 u16::from_be_bytes([self.register_data[off], self.register_data[off + 1]])
194 }
195
196 pub fn registers(&self) -> impl Iterator<Item = u16> + '_ {
198 self.register_data
199 .chunks_exact(2)
200 .map(|c| u16::from_be_bytes([c[0], c[1]]))
201 }
202
203 #[must_use]
205 pub fn raw(&self) -> &'buf [u8] {
206 self.register_data
207 }
208
209 pub fn decode(data: &'buf [u8]) -> Result<Self, DecodeError> {
217 if data.is_empty() {
218 return Err(DecodeError::Truncated {
219 expected: 1,
220 actual: 0,
221 });
222 }
223 let byte_count = data[0];
224 let register_data = &data[1..];
225 if register_data.len() != usize::from(byte_count) {
226 return Err(DecodeError::ByteCountMismatch {
227 declared: usize::from(byte_count),
228 actual: register_data.len(),
229 });
230 }
231 Ok(Self {
232 byte_count,
233 register_data,
234 })
235 }
236}
237
238impl Encode for ReadWriteMultipleRegistersResponse<'_> {
239 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
240 let len = self.encoded_len();
241 if buf.len() < len {
242 return Err(EncodeError::BufferTooSmall {
243 required: len,
244 available: buf.len(),
245 });
246 }
247 EncodeError::check_byte_count(usize::from(self.byte_count), self.register_data.len())?;
248 EncodeError::check_pdu_len(len)?;
249 buf[0] = FunctionCode::ReadWriteMultipleRegisters.code();
250 buf[1] = self.byte_count;
251 buf[2..2 + usize::from(self.byte_count)].copy_from_slice(self.register_data);
252 Ok(len)
253 }
254
255 fn encoded_len(&self) -> usize {
256 1 + 1 + usize::from(self.byte_count)
257 }
258}