use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("DNS resolution failed for '{host}': {message}")]
DnsResolution {
host: String,
message: String,
},
#[error("Failed to create socket: {0}")]
SocketCreation(#[source] io::Error),
#[error("Connection failed to {target}: {message}")]
ConnectionFailed {
target: String,
message: String,
},
#[error("Operation timed out after {timeout_ms}ms")]
Timeout {
timeout_ms: u64,
},
#[error("ICMP error: {0}")]
Icmp(String),
#[error("Permission denied - raw sockets require elevated privileges (CAP_NET_RAW on Linux)")]
PermissionDenied,
#[error("Invalid target: {0}")]
InvalidTarget(String),
#[error("IO error: {0}")]
Io(#[from] io::Error),
#[error("Host unreachable: {host}")]
HostUnreachable {
host: String,
},
#[error("Network unreachable")]
NetworkUnreachable,
#[error("Connection refused by {host}:{port}")]
ConnectionRefused {
host: String,
port: u16,
},
}
impl Error {
pub fn is_refused(&self) -> bool {
matches!(self, Error::ConnectionRefused { .. })
}
pub fn is_timeout(&self) -> bool {
matches!(self, Error::Timeout { .. })
}
pub fn is_permission_denied(&self) -> bool {
matches!(self, Error::PermissionDenied)
}
}