use thiserror::Error;
#[derive(Error, Debug)]
pub enum McpError {
#[error("subsystem discovery failed: {0}")]
Discovery(#[from] DiscoveryError),
#[error("transport error: {0}")]
Transport(String),
#[error("tool not found: '{name}'")]
ToolNotFound { name: String },
#[error("tool name malformed: '{name}' — {reason}")]
ToolNameMalformed { name: String, reason: String },
#[error("connection error: {0}")]
Connection(String),
#[error("protocol error: {0}")]
Protocol(String),
#[error("subsystem-specific: {0}")]
Subsystem(#[source] Box<dyn std::error::Error + Send + Sync>),
#[error("multiple errors: {}", .0.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("; "))]
Multiple(Vec<McpError>),
}
#[derive(Error, Debug)]
pub enum DiscoveryError {
#[error("device not found: {message}")]
NotFound { message: String },
#[error(
"device(s) found but requested port_index {requested} is out of range \
(found {found} matching VID:PID {vid:04x}:{pid:04x})"
)]
IndexOutOfRange {
requested: usize,
found: usize,
vid: u16,
pid: u16,
},
#[error("{count} devices matched — {hint}")]
Ambiguous { count: usize, hint: String },
#[error("permission denied accessing serial port")]
PermissionDenied,
#[error("--port value is empty (omit the flag entirely to enable auto-discovery)")]
InvalidPort,
#[error("serialport library error: {0}")]
Serial(#[from] serialport::Error),
}