tokio-gemini/src/error.rs

121 lines
3.1 KiB
Rust

//! Library error structures and enums
use tokio_rustls::rustls;
#[cfg(feature = "hickory")]
use hickory_client::{
error::ClientError as HickoryClientError, proto::error::ProtoError as HickoryProtoError,
};
/// Main error structure, also a wrapper for everything else
#[derive(Debug)]
pub enum LibError {
/// General I/O error
// TODO: separate somehow
IoError(std::io::Error),
/// URL parse or check error
InvalidUrlError(InvalidUrl),
/// DNS server has provided no suitable records
/// (e. g. domain does not exist)
HostLookupError,
/// TLS library error related to certificate/signature
/// verification failure or connection failure
RustlsError(rustls::Error),
/// Response status code is out of [10; 69] range
StatusOutOfRange(u8),
/// Response metadata or content cannot be parsed
/// as a UTF-8 string without errors
DataNotUtf8(std::string::FromUtf8Error),
/// Provided string is not a valid MIME type
InvalidMime(mime::FromStrError),
/// Hickory DNS client error
#[cfg(feature = "hickory")]
DnsClientError(HickoryClientError),
}
impl From<std::io::Error> for LibError {
#[inline]
fn from(err: std::io::Error) -> Self {
Self::IoError(err)
}
}
impl From<url::ParseError> for LibError {
#[inline]
fn from(err: url::ParseError) -> Self {
Self::InvalidUrlError(InvalidUrl::ParseError(err))
}
}
impl From<InvalidUrl> for LibError {
#[inline]
fn from(err: InvalidUrl) -> Self {
Self::InvalidUrlError(err)
}
}
impl From<rustls::Error> for LibError {
#[inline]
fn from(err: rustls::Error) -> Self {
Self::RustlsError(err)
}
}
impl From<rustls::CertificateError> for LibError {
#[inline]
fn from(err: rustls::CertificateError) -> Self {
Self::RustlsError(err.into())
}
}
impl LibError {
#[inline]
pub fn status_out_of_range(num: u8) -> Self {
Self::StatusOutOfRange(num)
}
}
impl From<std::string::FromUtf8Error> for LibError {
#[inline]
fn from(err: std::string::FromUtf8Error) -> Self {
Self::DataNotUtf8(err)
}
}
impl From<mime::FromStrError> for LibError {
#[inline]
fn from(err: mime::FromStrError) -> Self {
Self::InvalidMime(err)
}
}
#[cfg(feature = "hickory")]
impl From<HickoryClientError> for LibError {
#[inline]
fn from(err: HickoryClientError) -> Self {
Self::DnsClientError(err)
}
}
#[cfg(feature = "hickory")]
impl From<HickoryProtoError> for LibError {
#[inline]
fn from(err: HickoryProtoError) -> Self {
Self::DnsClientError(err.into())
}
}
/// URL parse or check error
#[derive(Debug)]
pub enum InvalidUrl {
/// Provided string cannot be parsed as a valid URL with [`url::Url`]
ParseError(url::ParseError),
/// URL scheme is not `gemini://`
SchemeNotGemini,
/// URL contains userinfo -- `user:pswd@` --
/// which is forbidden by Gemini spec
UserinfoPresent,
/// Could not extract host from the URL or convert host and port into
/// [`std::net::SocketAddr`] or [`crate::certs::ServerName`]
ConvertError,
}