rusty_modbus_codec/request/
bit_read.rs1use rusty_modbus_types::{Address, FunctionCode, Quantity};
4
5use crate::error::{DecodeError, EncodeError};
6use crate::request::Encode;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct ReadCoilsRequest {
13 pub address: Address,
15 pub quantity: Quantity,
17}
18
19impl ReadCoilsRequest {
20 const MAX_QUANTITY: u16 = 2000;
22
23 pub fn decode(data: &[u8]) -> Result<Self, DecodeError> {
31 DecodeError::check_exact_len(data, 4)?;
32 let address = Address(u16::from_be_bytes([data[0], data[1]]));
33 let quantity = u16::from_be_bytes([data[2], data[3]]);
34 if quantity == 0 || quantity > Self::MAX_QUANTITY {
35 return Err(DecodeError::QuantityOutOfRange { quantity });
36 }
37 Ok(Self {
38 address,
39 quantity: Quantity(quantity),
40 })
41 }
42}
43
44impl Encode for ReadCoilsRequest {
45 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
46 let len = self.encoded_len();
47 if buf.len() < len {
48 return Err(EncodeError::BufferTooSmall {
49 required: len,
50 available: buf.len(),
51 });
52 }
53 EncodeError::check_quantity(self.quantity.0, Self::MAX_QUANTITY)?;
54 EncodeError::check_pdu_len(len)?;
55 buf[0] = FunctionCode::ReadCoils.code();
56 buf[1..3].copy_from_slice(&self.address.0.to_be_bytes());
57 buf[3..5].copy_from_slice(&self.quantity.0.to_be_bytes());
58 Ok(len)
59 }
60
61 fn encoded_len(&self) -> usize {
62 5
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub struct ReadDiscreteInputsRequest {
71 pub address: Address,
73 pub quantity: Quantity,
75}
76
77impl ReadDiscreteInputsRequest {
78 const MAX_QUANTITY: u16 = 2000;
80
81 pub fn decode(data: &[u8]) -> Result<Self, DecodeError> {
89 DecodeError::check_exact_len(data, 4)?;
90 let address = Address(u16::from_be_bytes([data[0], data[1]]));
91 let quantity = u16::from_be_bytes([data[2], data[3]]);
92 if quantity == 0 || quantity > Self::MAX_QUANTITY {
93 return Err(DecodeError::QuantityOutOfRange { quantity });
94 }
95 Ok(Self {
96 address,
97 quantity: Quantity(quantity),
98 })
99 }
100}
101
102impl Encode for ReadDiscreteInputsRequest {
103 fn encode_into(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
104 let len = self.encoded_len();
105 if buf.len() < len {
106 return Err(EncodeError::BufferTooSmall {
107 required: len,
108 available: buf.len(),
109 });
110 }
111 EncodeError::check_quantity(self.quantity.0, Self::MAX_QUANTITY)?;
112 EncodeError::check_pdu_len(len)?;
113 buf[0] = FunctionCode::ReadDiscreteInputs.code();
114 buf[1..3].copy_from_slice(&self.address.0.to_be_bytes());
115 buf[3..5].copy_from_slice(&self.quantity.0.to_be_bytes());
116 Ok(len)
117 }
118
119 fn encoded_len(&self) -> usize {
120 5
121 }
122}