Skip to main content

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}