#![allow(missing_docs)]
#[allow(unused_imports)]
use crate::restart::{RestartResourceKind, RestartStateRecord};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ReconciliationDecision {
Recover,
Cleanup,
Quarantine,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ReconciliationPlanEntry {
record: RestartStateRecord,
action: ReconciliationDecision,
}
impl ReconciliationPlanEntry {
#[must_use]
pub const fn new(record: RestartStateRecord, action: ReconciliationDecision) -> Self {
Self { record, action }
}
#[must_use]
pub const fn record(&self) -> &RestartStateRecord {
&self.record
}
#[must_use]
pub const fn action(&self) -> ReconciliationDecision {
self.action
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ReconciliationPlan {
pub(crate) decisions: Vec<ReconciliationPlanEntry>,
}
impl ReconciliationPlan {
#[must_use]
pub fn from_records(records: impl IntoIterator<Item = RestartStateRecord>) -> Self {
let decisions = records
.into_iter()
.map(|record| {
let action = if record.id().is_empty() {
ReconciliationDecision::Quarantine
} else {
match record.kind() {
RestartResourceKind::ActiveVm | RestartResourceKind::SnapshotArtifact => {
ReconciliationDecision::Recover
}
RestartResourceKind::LogStream
| RestartResourceKind::StaleRuntimeProcess => {
ReconciliationDecision::Cleanup
}
}
};
ReconciliationPlanEntry::new(record, action)
})
.collect();
Self { decisions }
}
#[must_use]
pub fn decisions(&self) -> &[ReconciliationPlanEntry] {
&self.decisions
}
#[must_use]
pub fn decision_for(&self, id: &str) -> Option<ReconciliationDecision> {
self.decisions
.iter()
.find(|entry| entry.record.id() == id)
.map(ReconciliationPlanEntry::action)
}
}