1use std::fmt;
6
7#[derive(Debug)]
9pub enum SerialError {
10 OpenFailed(String),
12
13 PortClosed,
15
16 ReadError(String),
18
19 WriteError(String),
21
22 Timeout,
24
25 ConfigError(String),
27
28 PortNotFound(String),
30
31 PermissionDenied(String),
33
34 PortBusy(String),
36
37 IoError(String),
39
40 FrameError,
42
43 OverflowError,
45
46 ParityError,
48
49 Internal(String),
51}
52
53impl fmt::Display for SerialError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::OpenFailed(msg) => write!(f, "串口打开失败: {}", msg),
57 Self::PortClosed => write!(f, "串口已关闭"),
58 Self::ReadError(msg) => write!(f, "读取错误: {}", msg),
59 Self::WriteError(msg) => write!(f, "写入错误: {}", msg),
60 Self::Timeout => write!(f, "操作超时"),
61 Self::ConfigError(msg) => write!(f, "配置错误: {}", msg),
62 Self::PortNotFound(port) => write!(f, "串口不存在: {}", port),
63 Self::PermissionDenied(msg) => write!(f, "权限不足: {}", msg),
64 Self::PortBusy(port) => write!(f, "串口忙: {}", port),
65 Self::IoError(msg) => write!(f, "IO 错误: {}", msg),
66 Self::FrameError => write!(f, "帧错误"),
67 Self::OverflowError => write!(f, "溢出错误"),
68 Self::ParityError => write!(f, "校验错误"),
69 Self::Internal(msg) => write!(f, "内部错误: {}", msg),
70 }
71 }
72}
73
74impl std::error::Error for SerialError {}
75
76impl From<std::io::Error> for SerialError {
77 fn from(err: std::io::Error) -> Self {
78 use std::io::ErrorKind;
79 match err.kind() {
80 ErrorKind::NotFound => Self::PortNotFound(err.to_string()),
81 ErrorKind::PermissionDenied => Self::PermissionDenied(err.to_string()),
82 ErrorKind::TimedOut => Self::Timeout,
83 ErrorKind::WouldBlock => Self::Timeout,
84 _ => Self::IoError(err.to_string()),
85 }
86 }
87}
88
89impl From<serialport::Error> for SerialError {
90 fn from(err: serialport::Error) -> Self {
91 use serialport::ErrorKind;
92 match err.kind() {
93 ErrorKind::NoDevice => Self::PortNotFound(err.to_string()),
94 ErrorKind::InvalidInput => Self::ConfigError(err.to_string()),
95 ErrorKind::Io(kind) => match kind {
96 std::io::ErrorKind::PermissionDenied => Self::PermissionDenied(err.to_string()),
97 std::io::ErrorKind::TimedOut => Self::Timeout,
98 _ => Self::IoError(err.to_string()),
99 },
100 _ => Self::Internal(err.to_string()),
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_error_display() {
111 let err = SerialError::PortNotFound("COM1".into());
112 assert!(err.to_string().contains("COM1"));
113
114 let err = SerialError::Timeout;
115 assert!(err.to_string().contains("超时"));
116 }
117
118 #[test]
119 fn test_io_error_conversion() {
120 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "not found");
121 let serial_err: SerialError = io_err.into();
122 assert!(matches!(serial_err, SerialError::PortNotFound(_)));
123
124 let io_err = std::io::Error::new(std::io::ErrorKind::TimedOut, "timeout");
125 let serial_err: SerialError = io_err.into();
126 assert!(matches!(serial_err, SerialError::Timeout));
127 }
128}