use net_lattice_core::{Error, Result};
use net_lattice_model::{
Mutation, MutationExecutionPhase, MutationOperationReport, MutationOutcome, MutationPlan,
MutationPlanReport, MutationSnapshot, MutationStopReason, RollbackStatus,
};
pub type Cancellation<'a> = &'a mut dyn FnMut(usize, &Mutation) -> bool;
pub type Snapshot<'a> = &'a mut dyn FnMut(usize, &Mutation) -> Result<MutationSnapshot>;
pub type Compensation<'a> =
&'a mut dyn FnMut(usize, &Mutation, Option<&MutationSnapshot>) -> Result<()>;
pub struct ExecutionOptions<'a> {
pub(crate) cancellation: Option<Cancellation<'a>>,
pub(crate) snapshot: Option<Snapshot<'a>>,
pub(crate) compensation: Option<Compensation<'a>>,
}
impl<'a> ExecutionOptions<'a> {
pub fn new() -> Self {
Self {
cancellation: None,
snapshot: None,
compensation: None,
}
}
pub fn cancellation(mut self, callback: Cancellation<'a>) -> Self {
self.cancellation = Some(callback);
self
}
pub fn snapshot(mut self, callback: Snapshot<'a>) -> Self {
self.snapshot = Some(callback);
self
}
pub fn compensation(mut self, callback: Compensation<'a>) -> Self {
self.compensation = Some(callback);
self
}
}
impl Default for ExecutionOptions<'_> {
fn default() -> Self {
Self::new()
}
}
pub(crate) fn requires_dns_capability(operation: &Mutation) -> bool {
matches!(operation, Mutation::SetDnsConfig(_))
}
pub(crate) fn unsupported_plan_report(plan: &MutationPlan, error: Error) -> MutationPlanReport {
let mut outcomes = Vec::with_capacity(plan.len());
let mut reports = vec![MutationOperationReport::not_attempted(); plan.len()];
if !plan.is_empty() {
outcomes.push(MutationOutcome::Failed {
error,
may_have_applied: false,
});
outcomes.extend((0..plan.len() - 1).map(|_| MutationOutcome::NotAttempted));
reports[0] = MutationOperationReport {
phase: MutationExecutionPhase::Validation,
duration: std::time::Duration::ZERO,
stop_reason: Some(MutationStopReason::ValidationFailed),
};
}
MutationPlanReport::with_operation_reports(outcomes, RollbackStatus::NotNeeded, reports)
}