1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! Frame buffer sizing constants and helpers for Modbus RTU and TCP frames.
//!
//! Use the named constants or the `const fn` helpers when you need to know the
//! exact byte size of a Modbus frame for a given register count — for example,
//! when allocating application-level buffers or computing memory budgets.
//!
//! The [`Bridge`](crate::Bridge) itself uses full-spec internal buffers
//! (255 bytes for RTU, 261 bytes for TCP) and does not require any sizing from
//! this module.
//!
//! # Sizing rules
//!
//! For **bridge mode** (TCP → RTU), use the `TCP_*` constants — TCP frames
//! carry a 6-byte MBAP header that RTU frames do not, so TCP is always the
//! larger side.
//!
//! For **RTU-only** use cases, the `RTU_*` constants are sufficient.
//!
//! # Examples
//!
//! Compute a frame size at compile time using the `const fn` helpers:
//!
//! ```rust
//! use modbus_bridge::capacity::{rtu_capacity, tcp_capacity, REG_BYTES_16, REG_BYTES_32};
//!
//! // RTU frame size for 8 × 16-bit holding registers
//! const MY_RTU_BUF: usize = rtu_capacity(8, REG_BYTES_16);
//! assert_eq!(MY_RTU_BUF, 25); // 8×2 + 9 bytes overhead
//!
//! // TCP frame size for the same register count
//! const MY_TCP_BUF: usize = tcp_capacity(8, REG_BYTES_16);
//! assert_eq!(MY_TCP_BUF, 31); // 8×2 + 15 bytes overhead
//!
//! // RTU frame size for 4 × 32-bit register pairs
//! const MY_32BIT_BUF: usize = rtu_capacity(4, REG_BYTES_32);
//! assert_eq!(MY_32BIT_BUF, 25); // 4×4 + 9 bytes overhead
//! ```
//!
//! Or use a named constant directly:
//!
//! ```rust
//! use modbus_bridge::capacity::TCP_8R16;
//!
//! assert_eq!(TCP_8R16, 31);
//! ```
/// Bytes per standard 16-bit Modbus register.
pub const REG_BYTES_16: usize = 2;
/// Bytes per 32-bit value stored as two consecutive Modbus registers.
pub const REG_BYTES_32: usize = 4;
/// Computes the RTU frame buffer size in bytes for `n` registers of `reg_bytes` bytes each.
///
/// Sized for the worst case: a Write Multiple Registers request (FC 0x10):
/// `addr(1) + FC(1) + start(2) + qty(2) + byte_count(1) + data(n×b) + CRC(2) = n×b + 9`
///
/// Pass [`REG_BYTES_16`] for standard 16-bit registers or [`REG_BYTES_32`] for
/// 32-bit values stored across two consecutive registers.
///
/// # Examples
///
/// ```rust
/// use modbus_bridge::capacity::{rtu_capacity, REG_BYTES_16};
///
/// const BUF: usize = rtu_capacity(10, REG_BYTES_16);
/// assert_eq!(BUF, 29); // 10×2 + 9
/// ```
pub const
/// Computes the TCP frame buffer size in bytes for `n` registers of `reg_bytes` bytes each.
///
/// Sized for the worst case: a Write Multiple Registers request (FC 0x10) over TCP:
/// `MBAP(6) + addr(1) + FC(1) + start(2) + qty(2) + byte_count(1) + data(n×b) = n×b + 15`
///
/// The MBAP header adds 6 bytes over the equivalent RTU frame, so TCP buffers
/// are always larger than RTU buffers for the same register count.
///
/// # Examples
///
/// ```rust
/// use modbus_bridge::capacity::{tcp_capacity, REG_BYTES_16};
///
/// const BUF: usize = tcp_capacity(10, REG_BYTES_16);
/// assert_eq!(BUF, 35); // 10×2 + 15
/// ```
pub const
// ── Named RTU constants — 16-bit registers ────────────────────────────────────
/// RTU buffer: 1 × 16-bit register (11 B).
pub const RTU_1R16: usize = rtu_capacity;
/// RTU buffer: 4 × 16-bit registers (17 B).
pub const RTU_4R16: usize = rtu_capacity;
/// RTU buffer: 8 × 16-bit registers (25 B).
pub const RTU_8R16: usize = rtu_capacity;
/// RTU buffer: 10 × 16-bit registers (29 B).
pub const RTU_10R16: usize = rtu_capacity;
/// RTU buffer: 16 × 16-bit registers (41 B).
pub const RTU_16R16: usize = rtu_capacity;
/// RTU buffer: 32 × 16-bit registers (73 B).
pub const RTU_32R16: usize = rtu_capacity;
/// RTU buffer: 64 × 16-bit registers (137 B).
pub const RTU_64R16: usize = rtu_capacity;
/// RTU buffer: Modbus spec maximum — 123 × 16-bit registers (255 B).
pub const RTU_MAX: usize = rtu_capacity;
// ── Named RTU constants — 32-bit register pairs ───────────────────────────────
/// RTU buffer: 1 × 32-bit register pair (13 B).
pub const RTU_1R32: usize = rtu_capacity;
/// RTU buffer: 4 × 32-bit register pairs (25 B).
pub const RTU_4R32: usize = rtu_capacity;
/// RTU buffer: 8 × 32-bit register pairs (41 B).
pub const RTU_8R32: usize = rtu_capacity;
/// RTU buffer: 10 × 32-bit register pairs (49 B).
pub const RTU_10R32: usize = rtu_capacity;
/// RTU buffer: 32 × 32-bit register pairs (137 B).
pub const RTU_32R32: usize = rtu_capacity;
/// RTU buffer: spec maximum for 32-bit pairs — 61 pairs (253 B).
pub const RTU_MAX32: usize = rtu_capacity;
// ── Named TCP constants — 16-bit registers ────────────────────────────────────
/// TCP buffer: 1 × 16-bit register (17 B).
pub const TCP_1R16: usize = tcp_capacity;
/// TCP buffer: 4 × 16-bit registers (23 B).
pub const TCP_4R16: usize = tcp_capacity;
/// TCP buffer: 8 × 16-bit registers (31 B).
pub const TCP_8R16: usize = tcp_capacity;
/// TCP buffer: 10 × 16-bit registers (35 B).
pub const TCP_10R16: usize = tcp_capacity;
/// TCP buffer: 16 × 16-bit registers (47 B).
pub const TCP_16R16: usize = tcp_capacity;
/// TCP buffer: 32 × 16-bit registers (79 B).
pub const TCP_32R16: usize = tcp_capacity;
/// TCP buffer: 64 × 16-bit registers (143 B).
pub const TCP_64R16: usize = tcp_capacity;
/// TCP buffer: Modbus spec maximum — 123 × 16-bit registers (261 B).
pub const TCP_MAX: usize = tcp_capacity;
// ── Named TCP constants — 32-bit register pairs ───────────────────────────────
/// TCP buffer: 10 × 32-bit register pairs (55 B).
pub const TCP_10R32: usize = tcp_capacity;
/// TCP buffer: spec maximum for 32-bit pairs — 61 pairs (259 B).
pub const TCP_MAX32: usize = tcp_capacity;