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
151
152
//! # Modbus FIFO Queue Models
//!
//! This module defines the data structures for handling **Read FIFO Queue** (Function Code 0x18).
//!
//! In Modbus, a FIFO (First-In-First-Out) queue is a specialized structure where a set of
//! registers can be read from a single pointer address. When the client reads the FIFO
//! pointer, the server returns the current count of registers in the queue followed by
//! the register data itself.
//!
//! ## Key Components
//! - [`FifoQueue`]: A container for the registers retrieved from the FIFO.
//! - [`MAX_FIFO_QUEUE_COUNT_PER_PDU`]: The protocol limit for registers in one FIFO response.
//!
//! ## Protocol Limits
//! According to the Modbus specification, the FIFO count can range from 0 to 31 registers.
//! The response PDU includes a 2-byte byte count, a 2-byte FIFO count, and then the
//! register data (up to 62 bytes).
/// The maximum number of 16-bit registers that can be returned in a single Read FIFO Queue (FC 24) response.
///
/// The Modbus specification limits the FIFO count to 31 registers (62 bytes of data).
pub const MAX_FIFO_QUEUE_COUNT_PER_PDU: usize = 31;
/// A collection of register values retrieved from a Modbus FIFO queue.
///
/// This structure maintains the pointer address used for the request and stores the
/// resulting register values in a fixed-size array, making it suitable for `no_std`
/// and memory-constrained environments.
///
/// # Internal Representation
/// The `queue` field is a fixed-size array (`[u16; MAX_FIFO_QUEUE_COUNT_PER_PDU]`)
/// that stores the 16-bit register values. The `length` field tracks the actual
/// number of valid registers currently present in the `queue`, allowing the struct
/// to manage a variable number of registers within its fixed capacity.
///
/// # Examples
///
/// ```rust
/// use mbus_core::models::fifo_queue::FifoQueue;
/// use mbus_core::models::fifo_queue::MAX_FIFO_QUEUE_COUNT_PER_PDU;
///
/// // 1. Create a new FifoQueue instance for pointer address 0x1000.
/// // Initially, it's empty.
/// let mut fifo = FifoQueue::new(0x1000);
/// assert_eq!(fifo.ptr_address(), 0x1000);
/// assert_eq!(fifo.length(), 0);
/// assert!(fifo.queue().is_empty());
///
/// // 2. Simulate receiving a Modbus response with FIFO data.
/// // Let's say we read 3 registers: 0x1111, 0x2222, 0x3333.
/// // The `values` array would typically come from parsing the PDU.
/// let mut received_values = [0; MAX_FIFO_QUEUE_COUNT_PER_PDU];
/// received_values[0] = 0x1111;
/// received_values[1] = 0x2222;
/// received_values[2] = 0x3333;
/// let received_length = 3;
///
/// // 3. Populate the FifoQueue with the received data using `with_values`.
/// fifo = fifo.with_values(received_values, received_length);
///
/// // 4. Verify the contents and properties of the FIFO queue.
/// assert_eq!(fifo.length(), 3);
/// assert_eq!(fifo.queue()[..3], [0x1111, 0x2222, 0x3333]);
/// assert_eq!(fifo.queue()[..1], [0x1111]);
/// assert_eq!(fifo.queue()[1..2], [0x2222]);
/// assert_eq!(fifo.queue()[2..3], [0x3333]);
/// ```