use std::io::ErrorKind;
use std::num::ParseIntError;
use thiserror::Error as ThisError;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(ThisError, Debug)]
pub enum Error {
#[error(transparent)]
#[cfg(feature = "rustls")]
Tls(#[from] tokio_rustls::rustls::Error),
#[error(transparent)]
IO(#[from] std::io::Error),
#[error(transparent)]
Http(http::Error),
#[error(transparent)]
IntError(#[from] ParseIntError),
#[error(transparent)]
ReplyError(#[from] ReplyError),
#[error("other")]
Other(String),
}
#[derive(ThisError, Debug)]
pub enum ReplyError {
#[error("Succeeded")]
Succeeded,
#[error("General failure")]
GeneralFailure,
#[error("Connection not allowed by ruleset")]
ConnectionNotAllowed,
#[error("Network unreachable")]
NetworkUnreachable,
#[error("Host unreachable")]
HostUnreachable,
#[error("Connection refused")]
ConnectionRefused,
#[error("TTL expired")]
TtlExpired,
#[error("Command not supported")]
CommandNotSupported,
#[error("Address type not supported")]
AddressTypeNotSupported,
}
impl From<http::Error> for Error {
fn from(value: http::Error) -> Self {
let error = Error::Http(value);
tracing::error!("HTTP error: {}", error);
error
}
}
impl From<http::header::InvalidHeaderValue> for Error {
fn from(value: http::header::InvalidHeaderValue) -> Self {
let error = Error::Http(http::Error::from(value));
tracing::error!("Invalid header value error: {}", error);
error
}
}
pub(crate) fn new_io_error(error_kind: ErrorKind, msg: &str) -> Error {
let error = Error::IO(std::io::Error::new(error_kind, msg));
tracing::error!("IO error: {}", error);
error
}
impl Error {
pub(crate) fn invalid_request(msg: impl Into<String>) -> Error {
let error = Error::Other(msg.into());
tracing::error!("Invalid request: {}", error);
error
}
}
#[cfg(feature = "tls")]
pub(crate) fn builder<E: Into<Box<dyn std::error::Error + Send + Sync>>>(e: E) -> Error {
let error = Error::Other(e.into().to_string());
tracing::error!("Builder error: {}", error);
error
}