//! 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 for LibError { #[inline] fn from(err: std::io::Error) -> Self { Self::IoError(err) } } impl From for LibError { #[inline] fn from(err: url::ParseError) -> Self { Self::InvalidUrlError(InvalidUrl::ParseError(err)) } } impl From for LibError { #[inline] fn from(err: InvalidUrl) -> Self { Self::InvalidUrlError(err) } } impl From for LibError { #[inline] fn from(err: rustls::Error) -> Self { Self::RustlsError(err) } } impl From 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 for LibError { #[inline] fn from(err: std::string::FromUtf8Error) -> Self { Self::DataNotUtf8(err) } } impl From for LibError { #[inline] fn from(err: mime::FromStrError) -> Self { Self::InvalidMime(err) } } #[cfg(feature = "hickory")] impl From for LibError { #[inline] fn from(err: HickoryClientError) -> Self { Self::DnsClientError(err) } } #[cfg(feature = "hickory")] impl From 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, }