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;
9mod size_argument;
10pub mod write_multiple;
11
12/// Associates function code with function type.
13pub trait Code {
14    /// Modbus function code.
15    const CODE: u8;
16}
17
18/// Function response output.
19pub trait IntoValue {
20    type Value;
21
22    /// Unwrap the function response output.
23    fn into_value(self) -> Self::Value;
24}
25
26/// Read coils.
27///
28/// Type parameters bind to the address, value, and codec types.
29pub struct ReadCoils<A, V>(PhantomData<(A, V)>);
30
31impl<A, V> Code for ReadCoils<A, V> {
32    const CODE: u8 = 1;
33}
34
35impl<A, V> Function for ReadCoils<A, V>
36where
37    read_multiple::Args<A, V, size_argument::Bits>: Encode,
38    read_multiple::Output<V>: Decode,
39{
40    type Args = read_multiple::Args<A, V, size_argument::Bits>;
41    type Output = read_multiple::Output<V>;
42}
43
44/// Read discrete inputs.
45pub struct ReadDiscreteInputs<A, V>(PhantomData<(A, V)>);
46
47impl<A, V> Code for ReadDiscreteInputs<A, V> {
48    const CODE: u8 = 2;
49}
50
51impl<A, V> Function for ReadDiscreteInputs<A, V>
52where
53    read_multiple::Args<A, V, size_argument::Bits>: Encode,
54    read_multiple::Output<V>: Decode,
55{
56    type Args = read_multiple::Args<A, V, size_argument::Bits>;
57    type Output = read_multiple::Output<V>;
58}
59
60/// Read holding registers.
61pub struct ReadHoldingRegisters<A, V>(PhantomData<(A, V)>);
62
63impl<A, V> Code for ReadHoldingRegisters<A, V> {
64    const CODE: u8 = 3;
65}
66
67impl<A, V> Function for ReadHoldingRegisters<A, V>
68where
69    read_multiple::Args<A, V, size_argument::Words>: Encode,
70    read_multiple::Output<V>: Decode,
71{
72    type Args = read_multiple::Args<A, V, size_argument::Words>;
73    type Output = read_multiple::Output<V>;
74}
75
76/// Read input registers.
77pub struct ReadInputRegisters<A, V>(PhantomData<(A, V)>);
78
79impl<A, V> Code for ReadInputRegisters<A, V> {
80    const CODE: u8 = 4;
81}
82
83impl<A, V> Function for ReadInputRegisters<A, V>
84where
85    read_multiple::Args<A, V, size_argument::Words>: Encode,
86    read_multiple::Output<V>: Decode,
87{
88    type Args = read_multiple::Args<A, V, size_argument::Words>;
89    type Output = read_multiple::Output<V>;
90}
91
92/// Write multiple registers.
93pub struct WriteMultipleRegisters<A, V>(PhantomData<(A, V)>);
94
95impl<A, V> Code for WriteMultipleRegisters<A, V> {
96    const CODE: u8 = 16;
97}
98
99impl<A, V> Function for WriteMultipleRegisters<A, V>
100where
101    write_multiple::Args<A, V, size_argument::Words>: Encode,
102{
103    type Args = write_multiple::Args<A, V, size_argument::Words>;
104    type Output = write_multiple::Output;
105}