use async_trait::async_trait;
use chrono::{DateTime, Utc};
use crate::error::Result;
use crate::model::Model;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum SoftDeleteScope {
Disabled,
ActiveOnly,
WithTrashed,
OnlyTrashed,
}
pub(crate) fn query_scope_for<M: Model>(
include_trashed: bool,
only_trashed: bool,
) -> SoftDeleteScope {
if !M::soft_delete_enabled() {
SoftDeleteScope::Disabled
} else if only_trashed {
SoftDeleteScope::OnlyTrashed
} else if include_trashed {
SoftDeleteScope::WithTrashed
} else {
SoftDeleteScope::ActiveOnly
}
}
#[async_trait]
pub trait SoftDelete: Model {
fn deleted_at_column() -> &'static str {
"deleted_at"
}
fn deleted_at(&self) -> Option<DateTime<Utc>>;
fn set_deleted_at(&mut self, timestamp: Option<DateTime<Utc>>);
fn is_deleted(&self) -> bool {
self.deleted_at().is_some()
}
async fn soft_delete(mut self) -> Result<Self>
where
Self: Sized,
{
self.set_deleted_at(Some(Utc::now()));
self.update().await
}
async fn restore(mut self) -> Result<Self>
where
Self: Sized,
{
self.set_deleted_at(None);
self.update().await
}
async fn force_delete(self) -> Result<u64>
where
Self: Sized,
{
<Self as Model>::delete(self).await
}
}