use alloc::vec::Vec;
use super::{ObserverProgressAdvanceError, ObserverProgressTrackError, ObserverRecoveryAggregate};
use crate::wire::{
ConversationId, DeliverySeq, ObserverEpoch, ObserverRecoveryAccepted, ObserverRecoveryResponse,
};
#[derive(Debug, PartialEq, Eq)]
pub enum ObserverRecoveryTransactionDecision {
Respond {
aggregate: ObserverRecoveryAggregate,
response: ObserverRecoveryResponse,
},
Commit(ObserverRecoveryTransaction),
}
#[derive(Debug, PartialEq, Eq)]
pub struct ObserverRecoveryTransaction {
pub(super) aggregate: ObserverRecoveryAggregate,
pub(super) commit: ObserverRecoveryCommit,
}
impl ObserverRecoveryTransaction {
#[must_use]
pub fn arms(&self) -> &[ObserverRecoveryArm] {
self.commit.arms()
}
#[must_use]
pub const fn outcome(&self) -> &ObserverRecoveryAccepted {
self.commit.outcome()
}
#[must_use]
pub fn commit(mut self) -> (ObserverRecoveryAggregate, ObserverRecoveryAccepted) {
let (arms, outcome) = self.commit.into_parts();
for arm in arms {
self.aggregate
.armed
.insert(arm.conversation_id(), arm.refused_epoch());
}
(self.aggregate, outcome)
}
#[must_use]
pub fn abort(self) -> ObserverRecoveryAggregate {
self.aggregate
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum ObserverProgressAdvanceDecision {
Refuse {
aggregate: ObserverRecoveryAggregate,
error: ObserverProgressAdvanceError,
},
Commit(ObserverProgressAdvanceTransaction),
}
#[derive(Debug, PartialEq, Eq)]
pub struct ObserverProgressAdvanceTransaction {
pub(super) aggregate: ObserverRecoveryAggregate,
pub(super) conversation_id: ConversationId,
pub(super) presented_progress: DeliverySeq,
pub(super) fired: Option<ObserverRecoveryArm>,
}
impl ObserverProgressAdvanceTransaction {
#[must_use]
pub const fn conversation_id(&self) -> ConversationId {
self.conversation_id
}
#[must_use]
pub const fn presented_progress(&self) -> DeliverySeq {
self.presented_progress
}
#[must_use]
pub const fn fired_arm(&self) -> Option<ObserverRecoveryArm> {
self.fired
}
#[must_use]
pub fn commit(mut self) -> (ObserverRecoveryAggregate, Option<ObserverRecoveryArm>) {
self.aggregate
.progress
.insert(self.conversation_id, self.presented_progress);
if self.fired.is_some() {
self.aggregate.armed.remove(&self.conversation_id);
}
(self.aggregate, self.fired)
}
#[must_use]
pub fn abort(self) -> ObserverRecoveryAggregate {
self.aggregate
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum ObserverProgressTrackDecision {
Refuse {
aggregate: ObserverRecoveryAggregate,
error: ObserverProgressTrackError,
},
Commit(ObserverProgressTrackTransaction),
}
#[derive(Debug, PartialEq, Eq)]
pub struct ObserverProgressTrackTransaction {
pub(super) aggregate: ObserverRecoveryAggregate,
pub(super) conversation_id: ConversationId,
pub(super) observer_progress: DeliverySeq,
}
impl ObserverProgressTrackTransaction {
#[must_use]
pub const fn conversation_id(&self) -> ConversationId {
self.conversation_id
}
#[must_use]
pub const fn observer_progress(&self) -> DeliverySeq {
self.observer_progress
}
#[must_use]
pub fn commit(mut self) -> ObserverRecoveryAggregate {
self.aggregate
.progress
.insert(self.conversation_id, self.observer_progress);
self.aggregate
}
#[must_use]
pub fn abort(self) -> ObserverRecoveryAggregate {
self.aggregate
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ObserverRecoveryArm {
pub(super) conversation_id: ConversationId,
pub(super) refused_epoch: ObserverEpoch,
}
impl ObserverRecoveryArm {
#[must_use]
pub const fn conversation_id(self) -> ConversationId {
self.conversation_id
}
#[must_use]
pub const fn refused_epoch(self) -> ObserverEpoch {
self.refused_epoch
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ObserverRecoveryCommit {
pub(super) arms: Vec<ObserverRecoveryArm>,
pub(super) outcome: ObserverRecoveryAccepted,
}
impl ObserverRecoveryCommit {
#[must_use]
pub fn arms(&self) -> &[ObserverRecoveryArm] {
&self.arms
}
#[must_use]
pub const fn outcome(&self) -> &ObserverRecoveryAccepted {
&self.outcome
}
#[must_use]
pub fn into_parts(self) -> (Vec<ObserverRecoveryArm>, ObserverRecoveryAccepted) {
(self.arms, self.outcome)
}
}