Skip to main content

mbus_core/transport/
error.rs

1//! Transport-layer error and type-classification types.
2
3#[cfg(all(feature = "defmt-format", target_os = "none"))]
4use defmt;
5
6use crate::errors::MbusError;
7
8use super::config::SerialMode;
9
10/// Represents errors that can occur at the Modbus transport layer.
11#[derive(Debug, PartialEq, Eq)]
12pub enum TransportError {
13    /// The connection attempt failed.
14    ConnectionFailed,
15    /// The connection was unexpectedly closed.
16    ConnectionClosed,
17    /// An I/O error occurred during send or receive.
18    IoError,
19    /// A timeout occurred during a network operation.
20    Timeout,
21    /// The received data was too large for the buffer.
22    BufferTooSmall,
23    /// An unexpected error occurred.
24    Unexpected,
25    /// Invalid configuration.
26    InvalidConfiguration,
27}
28
29#[cfg(all(feature = "defmt-format", target_os = "none"))]
30impl defmt::Format for TransportError {
31    fn format(&self, f: defmt::Formatter) {
32        match self {
33            TransportError::ConnectionFailed => defmt::write!(f, "Connection failed"),
34            TransportError::ConnectionClosed => defmt::write!(f, "Connection closed"),
35            TransportError::IoError => defmt::write!(f, "I/O error"),
36            TransportError::Timeout => defmt::write!(f, "Timeout"),
37            TransportError::BufferTooSmall => defmt::write!(f, "Buffer too small"),
38            TransportError::Unexpected => defmt::write!(f, "An unexpected error occurred"),
39            TransportError::InvalidConfiguration => defmt::write!(f, "Invalid configuration"),
40        }
41    }
42}
43
44#[cfg(feature = "error-trait")]
45impl core::fmt::Display for TransportError {
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        match self {
48            TransportError::ConnectionFailed => write!(f, "Connection failed"),
49            TransportError::ConnectionClosed => write!(f, "Connection closed"),
50            TransportError::IoError => write!(f, "I/O error"),
51            TransportError::Timeout => write!(f, "Timeout"),
52            TransportError::BufferTooSmall => write!(f, "Buffer too small"),
53            TransportError::Unexpected => write!(f, "Unexpected error"),
54            TransportError::InvalidConfiguration => write!(f, "Invalid configuration"),
55        }
56    }
57}
58
59#[cfg(feature = "error-trait")]
60impl core::error::Error for TransportError {}
61
62impl From<TransportError> for MbusError {
63    fn from(err: TransportError) -> Self {
64        match err {
65            TransportError::ConnectionFailed => MbusError::ConnectionFailed,
66            TransportError::ConnectionClosed => MbusError::ConnectionClosed,
67            TransportError::IoError => MbusError::IoError,
68            TransportError::Timeout => MbusError::Timeout,
69            TransportError::BufferTooSmall => MbusError::BufferTooSmall,
70            TransportError::Unexpected => MbusError::Unexpected,
71            TransportError::InvalidConfiguration => MbusError::InvalidConfiguration,
72        }
73    }
74}
75
76/// An enumeration to specify the type of transport to use.
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum TransportType {
79    /// Standard library TCP transport implementation.
80    StdTcp,
81    /// Standard library Serial transport implementation.
82    StdSerial(SerialMode),
83    /// Custom TCP transport implementation.
84    CustomTcp,
85    /// Custom Serial transport implementation.
86    CustomSerial(SerialMode),
87}
88
89impl TransportType {
90    /// Returns `true` if the transport type is TCP (StdTcp or CustomTcp).
91    pub fn is_tcp_type(&self) -> bool {
92        matches!(self, TransportType::StdTcp | TransportType::CustomTcp)
93    }
94
95    /// Returns `true` if the transport type is serial (RTU or ASCII).
96    pub fn is_serial_type(&self) -> bool {
97        matches!(
98            self,
99            TransportType::StdSerial(_) | TransportType::CustomSerial(_)
100        )
101    }
102}