use topcoat::context::Cx;
use super::Resource;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Mutation {
Create,
Update,
Delete,
Action(&'static str),
}
#[derive(Debug, Clone)]
pub struct Committed<M> {
mutation: Mutation,
records: Vec<M>,
}
impl<M> Committed<M> {
pub fn created(record: M) -> Self {
Self {
mutation: Mutation::Create,
records: vec![record],
}
}
pub fn updated(record: M) -> Self {
Self {
mutation: Mutation::Update,
records: vec![record],
}
}
pub fn deleted(records: Vec<M>) -> Self {
Self {
mutation: Mutation::Delete,
records,
}
}
pub fn acted(name: &'static str, records: Vec<M>) -> Self {
Self {
mutation: Mutation::Action(name),
records,
}
}
pub fn mutation(&self) -> Mutation {
self.mutation
}
pub fn records(&self) -> &[M] {
&self.records
}
}
pub(crate) async fn run_after_commit<R: Resource>(cx: &Cx, committed: Committed<R::Model>) {
if let Err(error) = R::after_commit(cx, committed).await {
tracing::error!(
error = %error,
resource = std::any::type_name::<R>(),
"after_commit failed; the write stays committed"
);
}
}
#[cfg(test)]
mod tests;