//! Library error structures and enums #[cfg(feature = "hickory")] use hickory_client::{ error::ClientError as HickoryClientError, proto::error::ProtoError as HickoryProtoError, }; #[cfg(feature = "hickory")] use tokio::runtime::TryCurrentError; /// 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 provided no suitable records /// (e. g. domain does not exist) HostLookupError, /// 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 Client error #[cfg(feature = "hickory")] DnsClientError(HickoryClientError), /// Hickory Proto error #[cfg(feature = "hickory")] DnsProtoError(HickoryProtoError), /// Could not get Tokio runtime handle /// inside Rustls cert verifier #[cfg(feature = "hickory")] NoTokioRuntime(TryCurrentError), } 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 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::DnsProtoError(err) } } #[cfg(feature = "hickory")] impl From for LibError { #[inline] fn from(err: TryCurrentError) -> Self { Self::NoTokioRuntime(err) } } /// 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, }