use std::error::Error as StdError;
use crate::migration::{Migration, MigrationId};
pub type TernResult<T> = Result<T, Error>;
type BoxDynError = Box<dyn StdError + Send + Sync + 'static>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("error applying migrations {0}")]
Execute(#[source] BoxDynError),
#[error("error applying migration {{name: {1}, no_tx: {2}}}: {0}")]
ExecuteMigration(#[source] BoxDynError, MigrationId, bool),
#[error("runtime could not resolve query {0}")]
ResolveQuery(String),
#[error("could not parse migration query {0}")]
Sql(#[from] std::fmt::Error),
#[error("migration {0} applied but missing in source")]
VersionMissing(i64),
#[error("migration {0} modified since apply: applied {1}, source {2}")]
VersionModified(i64, String, String),
#[error("version {0} not found in source")]
VersionNotPresent(i64),
#[error("version {0} too old for the requested operation")]
VersionTooOld(i64),
#[error("version {0} too new for the requested operation")]
VersionTooNew(i64),
}
pub trait DatabaseError<T, E> {
fn tern_result(self) -> TernResult<T>;
fn void_tern_result(self) -> TernResult<()>;
fn tern_migration_result<M: Migration + ?Sized>(self, migration: &M) -> TernResult<T>;
fn void_tern_migration_result<M: Migration + ?Sized>(self, migration: &M) -> TernResult<()>;
}
impl<T, E> DatabaseError<T, E> for Result<T, E>
where
E: StdError + Send + Sync + 'static,
{
fn void_tern_result(self) -> TernResult<()> {
match self {
Err(e) => Err(Error::Execute(Box::new(e))),
_ => Ok(()),
}
}
fn void_tern_migration_result<M: Migration + ?Sized>(self, migration: &M) -> TernResult<()> {
match self {
Err(e) => Err(Error::ExecuteMigration(
Box::new(e),
migration.migration_id(),
migration.no_tx(),
)),
_ => Ok(()),
}
}
fn tern_result(self) -> TernResult<T> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(Error::Execute(Box::new(e))),
}
}
fn tern_migration_result<M: Migration + ?Sized>(self, migration: &M) -> TernResult<T> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(Error::ExecuteMigration(
Box::new(e),
migration.migration_id(),
migration.no_tx(),
)),
}
}
}