use super::{AttemptAuthorityRecord, AttemptJournalRecord};
#[derive(Debug)]
pub(crate) struct MutationReservation {
pub authority: AttemptAuthorityRecord,
pub mutation_attempt: u32,
}
impl MutationReservation {
pub(crate) fn new(
authority: AttemptAuthorityRecord,
journal: &AttemptJournalRecord,
) -> Result<Self, MutationReservationError> {
let mutation_attempt = journal
.pending_mutation()
.ok_or(MutationReservationError::NoPendingMutation)?;
let reservation = Self {
authority,
mutation_attempt,
};
reservation.validate(journal)?;
Ok(reservation)
}
pub(crate) fn validate(
&self,
journal: &AttemptJournalRecord,
) -> Result<(), MutationReservationError> {
journal.validate_pending_mutation(&self.authority, self.mutation_attempt)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
pub enum MutationReservationError {
#[error("original mutation requires a pending reservation")]
NoPendingMutation,
#[error("original mutation reservation authority mismatch")]
AuthorityMismatch,
#[error("original mutation reservation changed or settled")]
MutationMismatch,
#[error("original mutation reservation has a pending observation")]
ObservationPending,
}