1use crate::kind::InstrumentKind;
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum Error {
9 #[error("transport: {0}")]
10 Transport(#[from] TransportError),
11 #[error("backend: {0}")]
12 Backend(Box<dyn std::error::Error + Send + Sync>),
13 #[error("SCPI command '{command}' failed: {message}")]
14 ScpiCommand { command: String, message: String },
15 #[error("operation timed out")]
16 Timeout,
17 #[error("unsupported: {0}")]
18 Unsupported(&'static str),
19 #[error("device not found: {address}")]
20 DeviceNotFound { address: String },
21 #[error("kind {kind:?} not supported at {address}; supported: {supported:?}")]
22 UnsupportedKind {
23 address: String,
24 kind: InstrumentKind,
25 supported: Vec<InstrumentKind>,
26 },
27 #[error("parse error: {0}")]
28 Parse(String),
29 #[error("session limit reached for {address}")]
30 SessionLimit { address: String },
31 #[error("invalid address: {0}")]
32 InvalidAddress(String),
33 #[error("mock script exhausted: expected write")]
34 MockExhausted,
35 #[error("mock script mismatch: expected {expected:?}, got {actual:?}")]
36 MockMismatch { expected: String, actual: String },
37 #[error("communication failed at {address} after {attempts} attempt(s): {source}")]
38 Comm {
39 address: String,
40 command: Option<String>,
41 attempts: u32,
42 source: Box<dyn std::error::Error + Send + Sync>,
43 },
44}
45
46impl Error {
47 pub fn backend(err: impl std::error::Error + Send + Sync + 'static) -> Self {
49 Self::Backend(Box::new(err))
50 }
51
52 pub fn with_comm_context(
54 self,
55 address: impl Into<String>,
56 command: Option<&str>,
57 attempts: u32,
58 ) -> Self {
59 let address = address.into();
60 match self {
61 Self::Comm { .. } => self,
62 other => Self::Comm {
63 address,
64 command: command.map(str::to_string),
65 attempts,
66 source: Box::new(other),
67 },
68 }
69 }
70}
71
72#[derive(Debug, thiserror::Error)]
73#[non_exhaustive]
74pub enum TransportError {
75 #[error("I/O error: {0}")]
76 Io(String),
77 #[error("connection closed")]
78 Closed,
79}