Skip to main content

fennec_modbus/protocol/function/
read_write_multiple.rs

1use bytes::BufMut;
2
3use crate::protocol::{
4    Address,
5    codec::{BitSize, Encode},
6    function::{read_multiple, size_argument, size_argument::SizeArgument, write_multiple},
7};
8
9/// Address range for the reading operation along with address range and value for the writing operation.
10///
11/// # Example
12///
13/// ```rust
14/// use fennec_modbus::protocol::{codec::Encode, function::read_write_multiple::Args};
15///
16/// // Read six registers starting at register 4, and to write three
17/// // registers starting at register 15 (Modbus spec ยง6.17 example).
18/// assert_eq!(
19///     Args::<_, [u16; 6], _, _>::new(3, 14, [0x00FF_u16, 0x00FF, 0x00FF]).to_bytes(),
20///     [
21///         0x00, 0x03, // read starting address
22///         0x00, 0x06, // quantity of registers to read
23///         0x00, 0x0E, // write starting address
24///         0x00, 0x03, // quantity to write
25///         0x06, // write byte count
26///         0x00, 0xFF, // register 1
27///         0x00, 0xFF, // register 2
28///         0x00, 0xFF, // register 3
29///     ]
30/// );
31/// ```
32#[must_use]
33pub struct Args<ReadAddress, ReadValue, WriteAddress, WriteValue> {
34    read: read_multiple::Args<ReadAddress, ReadValue, size_argument::Words>,
35    write: write_multiple::Args<WriteAddress, WriteValue, size_argument::Words>,
36}
37
38impl<ReadAddress, ReadValue: BitSize, WriteAddress, WriteValue>
39    Args<ReadAddress, ReadValue, WriteAddress, WriteValue>
40{
41    pub const fn new(
42        read_address: ReadAddress,
43        write_address: WriteAddress,
44        write_value: WriteValue,
45    ) -> Self {
46        Self {
47            read: read_multiple::Args::new(read_address),
48            write: write_multiple::Args::new(write_address, write_value),
49        }
50    }
51}
52
53impl<ReadAddress, ReadValue, WriteAddress, WriteValue> Encode
54    for Args<ReadAddress, ReadValue, WriteAddress, WriteValue>
55where
56    ReadAddress: Address,
57    ReadValue: BitSize,
58    WriteAddress: Address,
59    WriteValue: BitSize + Encode,
60{
61    fn encode_to(&self, buf: &mut impl BufMut) {
62        size_argument::Words::assert_valid_size::<WriteValue, 242>();
63        self.read.encode_to(buf);
64        self.write.encode_to(buf);
65    }
66}