use std::io;
use std::time::Duration;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, EtherNetIpError>;
#[derive(Debug, Error)]
pub enum EtherNetIpError {
#[error("IO error: {0}")]
Io(#[from] io::Error),
#[error("Protocol error: {0}")]
Protocol(String),
#[error("Tag not found: {0}")]
TagNotFound(String),
#[error("Data type mismatch: expected {expected}, got {actual}")]
DataTypeMismatch { expected: String, actual: String },
#[error("Write error: {message} (status: {status})")]
WriteError { status: u8, message: String },
#[error("Read error: {message} (status: {status})")]
ReadError { status: u8, message: String },
#[error("Invalid response: {reason}")]
InvalidResponse { reason: String },
#[error("Operation timed out after {0:?}")]
Timeout(Duration),
#[error("UDT error: {0}")]
Udt(String),
#[error("Connection error: {0}")]
Connection(String),
#[error("Connection lost: {0}")]
ConnectionLost(String),
#[error("CIP error 0x{code:02X}: {message}")]
CipError { code: u8, message: String },
#[error("String too long: max length is {max_length}, but got {actual_length}")]
StringTooLong {
max_length: usize,
actual_length: usize,
},
#[error("Invalid string: {reason}")]
InvalidString { reason: String },
#[error("String write failed: {message} (status: {status})")]
StringWriteError { status: u8, message: String },
#[error("String read failed: {message} (status: {status})")]
StringReadError { status: u8, message: String },
#[error("Invalid string response: {reason}")]
InvalidStringResponse { reason: String },
#[error("Tag error: {0}")]
Tag(String),
#[error("Permission denied: {0}")]
Permission(String),
#[error("UTF-8 error: {0}")]
Utf8(#[from] std::string::FromUtf8Error),
#[error("Other error: {0}")]
Other(String),
#[error("Subscription error: {0}")]
Subscription(String),
}
impl EtherNetIpError {
pub fn is_retriable(&self) -> bool {
matches!(
self,
EtherNetIpError::Timeout(_)
| EtherNetIpError::Connection(_)
| EtherNetIpError::ConnectionLost(_)
| EtherNetIpError::Io(_)
)
}
}