Skip to main content

fennec_modbus/protocol/
function.rs

1use core::marker::PhantomData;
2
3use crate::protocol::{
4    Function,
5    codec::{Decode, Encode},
6};
7
8pub mod read_multiple;
9pub mod read_write_multiple;
10pub mod size_argument;
11pub mod write_multiple;
12
13/// Associates function code with function type.
14pub trait Code {
15    /// Modbus function code.
16    const CODE: u8;
17}
18
19/// Function response output.
20pub trait IntoValue {
21    type Value;
22
23    /// Unwrap the function response output.
24    fn into_value(self) -> Self::Value;
25}
26
27/// Read coils.
28///
29/// Type parameters bind to the address, value, and codec types.
30#[must_use]
31pub struct ReadCoils<A, V>(PhantomData<(A, V)>);
32
33impl<A, V> Code for ReadCoils<A, V> {
34    const CODE: u8 = 1;
35}
36
37impl<A, V> Function for ReadCoils<A, V>
38where
39    read_multiple::Args<A, V, size_argument::Bits>: Encode,
40    read_multiple::Output<V>: Decode,
41{
42    type Args = read_multiple::Args<A, V, size_argument::Bits>;
43    type Output = read_multiple::Output<V>;
44}
45
46/// Read discrete inputs.
47#[must_use]
48pub struct ReadDiscreteInputs<A, V>(PhantomData<(A, V)>);
49
50impl<A, V> Code for ReadDiscreteInputs<A, V> {
51    const CODE: u8 = 2;
52}
53
54impl<A, V> Function for ReadDiscreteInputs<A, V>
55where
56    read_multiple::Args<A, V, size_argument::Bits>: Encode,
57    read_multiple::Output<V>: Decode,
58{
59    type Args = read_multiple::Args<A, V, size_argument::Bits>;
60    type Output = read_multiple::Output<V>;
61}
62
63/// Read holding registers.
64#[must_use]
65pub struct ReadHoldingRegisters<A, V>(PhantomData<(A, V)>);
66
67impl<A, V> Code for ReadHoldingRegisters<A, V> {
68    const CODE: u8 = 3;
69}
70
71impl<A, V> Function for ReadHoldingRegisters<A, V>
72where
73    read_multiple::Args<A, V, size_argument::Words>: Encode,
74    read_multiple::Output<V>: Decode,
75{
76    type Args = read_multiple::Args<A, V, size_argument::Words>;
77    type Output = read_multiple::Output<V>;
78}
79
80/// Read input registers.
81#[must_use]
82pub struct ReadInputRegisters<A, V>(PhantomData<(A, V)>);
83
84impl<A, V> Code for ReadInputRegisters<A, V> {
85    const CODE: u8 = 4;
86}
87
88impl<A, V> Function for ReadInputRegisters<A, V>
89where
90    read_multiple::Args<A, V, size_argument::Words>: Encode,
91    read_multiple::Output<V>: Decode,
92{
93    type Args = read_multiple::Args<A, V, size_argument::Words>;
94    type Output = read_multiple::Output<V>;
95}
96
97/// Write multiple registers.
98#[must_use]
99pub struct WriteMultipleRegisters<A, V>(PhantomData<(A, V)>);
100
101impl<A, V> Code for WriteMultipleRegisters<A, V> {
102    const CODE: u8 = 16;
103}
104
105impl<A, V> Function for WriteMultipleRegisters<A, V>
106where
107    write_multiple::Args<A, V, size_argument::Words>: Encode,
108{
109    type Args = write_multiple::Args<A, V, size_argument::Words>;
110    type Output = write_multiple::Output;
111}
112
113/// Read and write multiple registers.
114///
115/// The write operation is performed *before* the read.
116#[must_use]
117pub struct ReadWriteRegisters<ReadAddress, ReadValue, WriteAddress, WriteValue>(
118    /// Binding to the address type to read.
119    PhantomData<ReadAddress>,
120    /// Binding to the value type to read.
121    PhantomData<ReadValue>,
122    /// Binding to the address type to write.
123    PhantomData<WriteAddress>,
124    /// Binding to the value type to write.
125    PhantomData<WriteValue>,
126);
127
128impl<ReadAddress, ReadValue, WriteAddress, WriteValue> Code
129    for ReadWriteRegisters<ReadAddress, ReadValue, WriteAddress, WriteValue>
130{
131    const CODE: u8 = 23;
132}
133
134impl<ReadAddress, ReadValue, WriteAddress, WriteValue> Function
135    for ReadWriteRegisters<ReadAddress, ReadValue, WriteAddress, WriteValue>
136where
137    read_write_multiple::Args<ReadAddress, ReadValue, WriteAddress, WriteValue>: Encode,
138    read_multiple::Output<ReadValue>: Decode,
139{
140    type Args = read_write_multiple::Args<ReadAddress, ReadValue, WriteAddress, WriteValue>;
141    type Output = read_multiple::Output<ReadValue>;
142}