1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum NanonisError {
5 #[error("IO error: {context}")]
7 Io {
8 #[source]
9 source: std::io::Error,
10 context: String,
11 },
12
13 #[error("Connection timeout")]
14 Timeout,
15
16 #[error("Protocol error: {0}")]
17 Protocol(String),
18
19 #[error("Type error: {0}")]
20 Type(String),
21
22 #[error("Command mismatch: expected {expected}, got {actual}")]
23 CommandMismatch { expected: String, actual: String },
24
25 #[error("Invalid command: {0}")]
26 InvalidCommand(String),
27
28 #[error("Invalid response: {0}")]
29 InvalidResponse(String),
30
31 #[error("Nanonis server error: {message} (code: {code})")]
33 ServerError { code: i32, message: String },
34
35 #[error("Command rejected: {0}")]
37 CommandRejected(String),
38
39 #[error("Invalid address: {0}")]
40 InvalidAddress(String),
41
42 #[error("Serialization error: {0}")]
43 SerializationError(String),
44}
45
46impl NanonisError {
47 pub fn is_server_error(&self) -> bool {
49 matches!(
50 self,
51 NanonisError::ServerError { .. } | NanonisError::CommandRejected(_)
52 )
53 }
54
55 pub fn error_code(&self) -> Option<i32> {
57 match self {
58 NanonisError::ServerError { code, .. } => Some(*code),
59 _ => None,
60 }
61 }
62}
63
64impl From<std::io::Error> for NanonisError {
66 fn from(error: std::io::Error) -> Self {
67 NanonisError::Io {
68 source: error,
69 context: "IO operation failed".to_string(),
70 }
71 }
72}
73
74impl From<serde_json::Error> for NanonisError {
75 fn from(error: serde_json::Error) -> Self {
76 NanonisError::SerializationError(error.to_string())
77 }
78}