use crate::entities::{AuditFact, AuditRecord, CeremonyInstance};
use crate::error::DomainError;
use crate::value_objects::{CeremonyRevision, ExpectedRevision, OutboxMessage};
#[derive(Debug, Clone, PartialEq)]
pub struct CeremonyCommit {
instance: CeremonyInstance,
expected_revision: ExpectedRevision,
facts: Vec<AuditFact>,
messages: Vec<OutboxMessage>,
}
impl CeremonyCommit {
pub fn new(
instance: CeremonyInstance,
expected_revision: ExpectedRevision,
facts: impl IntoIterator<Item = AuditFact>,
messages: impl IntoIterator<Item = OutboxMessage>,
) -> Result<Self, DomainError> {
let facts = facts.into_iter().collect::<Vec<_>>();
if facts.iter().any(|fact| &fact.ceremony_id != instance.id()) {
return Err(DomainError::InvariantViolated {
reason: "a commit cannot carry audit facts from another ceremony",
});
}
Ok(Self {
instance,
expected_revision,
facts,
messages: messages.into_iter().collect(),
})
}
#[must_use]
pub fn instance(&self) -> &CeremonyInstance {
&self.instance
}
#[must_use]
pub fn expected_revision(&self) -> ExpectedRevision {
self.expected_revision
}
#[must_use]
pub fn facts(&self) -> &[AuditFact] {
&self.facts
}
#[must_use]
pub fn messages(&self) -> &[OutboxMessage] {
&self.messages
}
#[must_use]
pub fn into_parts(
self,
) -> (
CeremonyInstance,
ExpectedRevision,
Vec<AuditFact>,
Vec<OutboxMessage>,
) {
(
self.instance,
self.expected_revision,
self.facts,
self.messages,
)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum CommitOutcome {
Committed {
revision: CeremonyRevision,
records: Vec<AuditRecord>,
},
Conflict {
expected: ExpectedRevision,
stored: Option<CeremonyRevision>,
},
}
impl CommitOutcome {
#[must_use]
pub fn committed_revision(&self) -> Option<CeremonyRevision> {
match self {
Self::Committed { revision, .. } => Some(*revision),
Self::Conflict { .. } => None,
}
}
#[must_use]
pub fn records(&self) -> &[AuditRecord] {
match self {
Self::Committed { records, .. } => records,
Self::Conflict { .. } => &[],
}
}
#[must_use]
pub fn is_conflict(&self) -> bool {
matches!(self, Self::Conflict { .. })
}
}