use crate::app::context::AppContext;
use crate::error::RoadsterResult;
use async_trait::async_trait;
use axum_core::extract::FromRef;
use serde_derive::Serialize;
use strum_macros::{EnumString, IntoStaticStr};
#[cfg(feature = "db-diesel")]
pub mod diesel;
#[cfg(feature = "db-sea-orm")]
pub mod sea_orm;
#[serde_with::skip_serializing_none]
#[derive(Debug, Serialize, bon::Builder)]
#[cfg_attr(feature = "cli", derive(clap::Parser))]
#[non_exhaustive]
pub struct UpArgs {
#[cfg_attr(feature = "cli", clap(short = 'n', long))]
pub steps: Option<usize>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Serialize, bon::Builder)]
#[cfg_attr(feature = "cli", derive(clap::Parser))]
#[non_exhaustive]
pub struct DownArgs {
#[cfg_attr(feature = "cli", clap(short = 'n', long))]
pub steps: Option<usize>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Serialize, bon::Builder)]
pub struct MigrationInfo {
pub name: String,
pub status: MigrationStatus,
}
#[derive(Debug, Serialize, EnumString, IntoStaticStr)]
pub enum MigrationStatus {
Applied,
Pending,
}
#[cfg_attr(test, mockall::automock)]
#[async_trait]
pub trait Migrator<S>: Send + Sync
where
S: Clone + Send + Sync + 'static,
AppContext: FromRef<S>,
{
async fn up(&self, state: &S, args: &UpArgs) -> RoadsterResult<usize>;
async fn down(&self, state: &S, args: &DownArgs) -> RoadsterResult<usize>;
async fn status(&self, state: &S) -> RoadsterResult<Vec<MigrationInfo>>;
}