use std::marker::PhantomData;
use autumn_web::AutumnResult;
use autumn_web::hooks::{MutationContext, MutationHooks};
use autumn_web::search::SearchIndexed;
use crate::jobs::{REINDEX_JOB, ReindexArgs};
pub async fn enqueue_reindex(args: &ReindexArgs) -> AutumnResult<()> {
autumn_web::job::enqueue(REINDEX_JOB, serde_json::to_value(args)?).await
}
pub async fn enqueue_reindex_for<M: SearchIndexed>(record: &M) -> AutumnResult<()> {
enqueue_reindex(&ReindexArgs::upsert(M::SEARCH_INDEX, record.search_id())).await
}
pub async fn enqueue_unindex_for<M: SearchIndexed>(record: &M) -> AutumnResult<()> {
enqueue_reindex(&ReindexArgs::delete(M::SEARCH_INDEX, record.search_id())).await
}
pub struct SearchSyncHooks<M, N, U> {
_model: ModelMarker<M, N, U>,
}
type ModelMarker<M, N, U> = PhantomData<fn() -> (M, N, U)>;
impl<M, N, U> SearchSyncHooks<M, N, U> {
#[must_use]
pub const fn new() -> Self {
Self {
_model: PhantomData,
}
}
}
impl<M, N, U> Default for SearchSyncHooks<M, N, U> {
fn default() -> Self {
Self::new()
}
}
impl<M, N, U> Clone for SearchSyncHooks<M, N, U> {
fn clone(&self) -> Self {
Self::new()
}
}
impl<M, N, U> std::fmt::Debug for SearchSyncHooks<M, N, U> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("SearchSyncHooks")
}
}
impl<M, N, U> MutationHooks for SearchSyncHooks<M, N, U>
where
M: SearchIndexed,
N: Send + Sync + 'static,
U: Send + Sync + 'static,
{
type Model = M;
type NewModel = N;
type UpdateModel = U;
fn after_create_commit(
&self,
_ctx: &mut MutationContext,
record: &Self::Model,
) -> impl Future<Output = AutumnResult<()>> + Send {
let args = ReindexArgs::upsert(M::SEARCH_INDEX, record.search_id());
async move { enqueue_reindex(&args).await }
}
fn after_update_commit(
&self,
_ctx: &mut MutationContext,
record: &Self::Model,
) -> impl Future<Output = AutumnResult<()>> + Send {
let args = ReindexArgs::upsert(M::SEARCH_INDEX, record.search_id());
async move { enqueue_reindex(&args).await }
}
fn after_delete_commit(
&self,
_ctx: &mut MutationContext,
record: &Self::Model,
) -> impl Future<Output = AutumnResult<()>> + Send {
let args = ReindexArgs::delete(M::SEARCH_INDEX, record.search_id());
async move { enqueue_reindex(&args).await }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_hooks_type_is_default_and_clone_as_repositories_require() {
struct NotClonable;
let hooks: SearchSyncHooks<NotClonable, NotClonable, NotClonable> =
SearchSyncHooks::default();
let _cloned = hooks.clone();
assert_eq!(format!("{hooks:?}"), "SearchSyncHooks");
}
}