use vantage_core::Result;
use vantage_types::{EmptyEntity, Entity, InvariantValue, Record};
use super::invariants::enforce_invariants;
use crate::table::{AfterFn, BeforeDeleteFn, BeforeFn, HookReturn, Phase, Table};
use crate::traits::table_source::TableSource;
impl<T: TableSource, E: Entity<T::Value>> Table<T, E>
where
T::Value: InvariantValue,
{
pub async fn prepare_insert(&self, record: &Record<T::Value>) -> Result<Record<T::Value>> {
self.require_confined_writes("insert")?;
let mut record = record.clone();
run_before(
self.before_insert_hooks(),
&mut record,
self.as_entity_erased(),
)
.await?;
self.strip_imported_columns(&mut record);
enforce_invariants(&mut record, self.invariants())?;
Ok(record)
}
pub async fn finish_insert(&self, id: &T::Id, record: &Record<T::Value>) -> Result<()> {
run_after(
self.after_insert_hooks(),
id,
record,
self.as_entity_erased(),
)
.await
}
}
pub(crate) async fn run_before<T: TableSource>(
hooks: &[(Phase, BeforeFn<T>)],
record: &mut Record<T::Value>,
table: &Table<T, EmptyEntity>,
) -> Result<()> {
for (_phase, hook) in hooks {
hook(record, table).await?;
}
Ok(())
}
pub(crate) async fn run_after<T: TableSource>(
hooks: &[AfterFn<T>],
id: &T::Id,
record: &Record<T::Value>,
table: &Table<T, EmptyEntity>,
) -> Result<()> {
for hook in hooks {
hook(id, record, table).await?;
}
Ok(())
}
pub(crate) async fn run_before_delete<T: TableSource>(
hooks: &[BeforeDeleteFn<T>],
id: &T::Id,
record: &Record<T::Value>,
table: &Table<T, EmptyEntity>,
) -> Result<HookReturn> {
for hook in hooks {
if let HookReturn::Handled = hook(id, record, table).await? {
return Ok(HookReturn::Handled);
}
}
Ok(HookReturn::Proceed)
}