#![warn(clippy::all, missing_docs, nonstandard_style, future_incompatible)]
use std::{error::Error, fmt, option::Option};
#[derive(Debug)]
pub struct SqlxError(::sqlx_core::error::Error, String);
pub type SqlxResult<T> = Result<T, SqlxError>;
#[macro_export]
macro_rules! sqlx_error {
() => {
|e| $crate::SqlxError::new(e, $crate::__private::code_path::code_path!().into())
};
($desc:expr) => {
|e| {
$crate::SqlxError::new(
e,
format!(
"{} in {}",
$desc,
$crate::__private::code_path::code_path!()
),
)
}
};
}
#[doc(hidden)]
pub mod __private {
pub use code_path;
}
impl SqlxError {
pub fn new(err: sqlx_core::error::Error, msg: String) -> Self {
Self(err, msg)
}
}
impl fmt::Display for SqlxError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "sqlx: {}", self.1)
}
}
impl Error for SqlxError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Option::Some(&self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug, thiserror::Error)]
pub enum MyError {
#[error(transparent)]
Sqlx(#[from] SqlxError),
}
fn bare() -> Result<(), MyError> {
Err(sqlx::Error::RowNotFound).map_err(sqlx_error!())?;
Ok(())
}
fn with_context() -> Result<(), MyError> {
Err(sqlx::Error::RowNotFound).map_err(sqlx_error!("my context"))?;
Ok(())
}
#[test]
fn works() {
assert!(bare()
.unwrap_err()
.to_string()
.starts_with("sqlx: sqlx_error::tests::bare at src/lib.rs:"));
assert!(with_context()
.unwrap_err()
.to_string()
.starts_with("sqlx: my context in sqlx_error::tests::with_context at src/lib.rs:"));
}
}