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