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 { 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}