rust_ethernet_ip/batch.rs
1use crate::PlcValue;
2
3// =========================================================================
4// BATCH OPERATIONS DATA STRUCTURES
5// =========================================================================
6
7/// Represents a single operation in a batch request
8///
9/// This enum defines the different types of operations that can be
10/// performed in a batch. Each operation specifies whether it's a read
11/// or write operation and includes the necessary parameters.
12#[derive(Debug, Clone)]
13pub enum BatchOperation {
14 /// Read operation for a specific tag
15 ///
16 /// # Fields
17 ///
18 /// * `tag_name` - The name of the tag to read
19 Read {
20 /// Fully qualified symbolic tag to read.
21 tag_name: String,
22 },
23
24 /// Write operation for a specific tag with a value
25 ///
26 /// # Fields
27 ///
28 /// * `tag_name` - The name of the tag to write
29 /// * `value` - The value to write to the tag
30 Write {
31 /// Fully qualified symbolic tag to write.
32 tag_name: String,
33 /// Value to write.
34 value: PlcValue,
35 },
36}
37
38/// Result of a single operation in a batch request
39///
40/// This structure contains the result of executing a single batch operation,
41/// including success/failure status and the actual data or error information.
42#[derive(Debug, Clone)]
43pub struct BatchResult {
44 /// The original operation that was executed
45 pub operation: BatchOperation,
46
47 /// The result of the operation
48 pub result: std::result::Result<Option<PlcValue>, BatchError>,
49
50 /// Execution time for this specific operation (in microseconds)
51 pub execution_time_us: u64,
52}
53
54/// Specific error types that can occur during batch operations
55///
56/// This enum provides detailed error information for batch operations,
57/// allowing for better error handling and diagnostics.
58#[derive(Debug, Clone, thiserror::Error)]
59#[non_exhaustive]
60pub enum BatchError {
61 /// Tag was not found in the PLC
62 #[error("Tag not found: {0}")]
63 TagNotFound(String),
64
65 /// Data type mismatch between expected and actual
66 #[error("Data type mismatch: expected {expected}, got {actual}")]
67 DataTypeMismatch {
68 /// Data type required by the target.
69 expected: String,
70 /// Data type supplied by the operation.
71 actual: String,
72 },
73
74 /// Network communication error
75 #[error("Network error: {0}")]
76 NetworkError(String),
77
78 /// CIP protocol error with status code
79 #[error("CIP error (0x{status:02X}): {message}")]
80 CipError {
81 /// CIP general status code.
82 status: u8,
83 /// Human-readable controller response.
84 message: String,
85 },
86
87 /// Tag name parsing error
88 #[error("Tag path error: {0}")]
89 TagPathError(String),
90
91 /// Value serialization/deserialization error
92 #[error("Serialization error: {0}")]
93 SerializationError(String),
94
95 /// Operation timeout
96 #[error("Operation timeout")]
97 Timeout,
98
99 /// Generic error for unexpected issues
100 #[error("Error: {0}")]
101 Other(String),
102}
103
104/// Configuration for batch operations
105///
106/// This structure controls the behavior and performance characteristics
107/// of batch read/write operations. Proper tuning can significantly
108/// improve throughput for applications that need to process many tags.
109#[derive(Debug, Clone)]
110pub struct BatchConfig {
111 /// Maximum number of operations to include in a single CIP packet
112 ///
113 /// Larger values improve performance but may exceed PLC packet size limits.
114 /// Typical range: 10-50 operations per packet.
115 pub max_operations_per_packet: usize,
116
117 /// Maximum packet size in bytes for batch operations
118 ///
119 /// Should not exceed the PLC's maximum packet size capability.
120 /// Typical values: 504 bytes (default), up to 4000 bytes for modern PLCs.
121 pub max_packet_size: usize,
122
123 /// Timeout for individual batch packets (in milliseconds)
124 ///
125 /// This is per-packet timeout, not per-operation.
126 /// Typical range: 1000-5000 milliseconds.
127 pub packet_timeout_ms: u64,
128
129 /// Whether to continue processing other operations if one fails
130 ///
131 /// If true, failed operations are reported but don't stop the batch.
132 /// If false, the first error stops the entire batch processing.
133 pub continue_on_error: bool,
134
135 /// Whether to optimize packet packing by grouping similar operations
136 ///
137 /// If true, reads and writes are grouped separately for better performance.
138 /// If false, operations are processed in the order provided.
139 pub optimize_packet_packing: bool,
140}
141
142impl Default for BatchConfig {
143 fn default() -> Self {
144 Self {
145 max_operations_per_packet: 20,
146 max_packet_size: 504, // Conservative default for maximum compatibility
147 packet_timeout_ms: 3000,
148 continue_on_error: true,
149 optimize_packet_packing: true,
150 }
151 }
152}