use std::borrow::Cow; use std::error::Error as StdError; use std::fmt::{self, Display, Formatter}; mod database; pub use database::DatabaseError; /// `Result` type returned from methods that can have SQLx errors. pub type Result = std::result::Result; #[derive(Debug)] #[non_exhaustive] pub enum Error { Configuration { message: Cow<'static, str>, source: Option> }, Connect(Box), Network(std::io::Error), } impl Error { #[doc(hidden)] pub fn connect(error: E) -> Self where E: DatabaseError, { Self::Connect(Box::new(error)) } #[doc(hidden)] pub fn configuration( message: impl Into>, source: impl Into>, ) -> Self { Self::Configuration { message: message.into(), source: Some(source.into()) } } #[doc(hidden)] pub fn configuration_msg(message: impl Into>) -> Self { Self::Configuration { message: message.into(), source: None } } } impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Self::Network(source) => write!(f, "{}", source), Self::Connect(source) => write!(f, "{}", source), Self::Configuration { message, source: None } => { write!(f, "{}", message) } Self::Configuration { message, source: Some(source) } => { write!(f, "{}: {}", message, source) } } } } impl StdError for Error { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { Self::Configuration { source: Some(source), .. } => Some(&**source), Self::Network(source) => Some(source), _ => None, } } } impl From for Error { fn from(error: std::io::Error) -> Self { Self::Network(error) } } impl From for Error { fn from(error: std::io::ErrorKind) -> Self { Self::Network(error.into()) } }