sim_lib_operation_gate/
lifecycle_record.rs1use sim_kernel::Datum;
4
5use crate::{
6 OperationAttempt, OperationError, OperationGrant, OperationId, OperationIntent,
7 lifecycle::{
8 FencedDispatch, LifecycleReceipt, OUTCOME_TAG, OperationLease, OperationObservation,
9 OperationOutcome, OperationOutcomeId, OperationStep,
10 },
11 lifecycle_wire::{outcome_datum, outcome_from_datum},
12 operation_wire::{content_id, field, id_from_datum, node_fields},
13};
14
15#[derive(Clone, Debug, PartialEq, Eq)]
17pub(super) struct IdentifiedOutcome {
18 pub(super) id: OperationOutcomeId,
19 pub(super) operation: OperationId,
20 pub(super) outcome: OperationOutcome,
21}
22
23impl IdentifiedOutcome {
24 pub(super) fn new(
25 operation: OperationId,
26 outcome: OperationOutcome,
27 ) -> Result<Self, OperationError> {
28 let datum = outcome_datum(&operation, &outcome);
29 Ok(Self {
30 id: OperationOutcomeId(content_id(&datum)?),
31 operation,
32 outcome,
33 })
34 }
35 pub(super) fn from_datum(datum: &Datum) -> Result<Self, OperationError> {
36 let fields = node_fields(datum, OUTCOME_TAG, 3)?;
37 let operation = OperationId(id_from_datum(field(fields, "operation")?)?);
38 let outcome = outcome_from_datum(field(fields, "value")?)?;
39 let value = Self::new(operation, outcome)?;
40 if value.canonical_datum() != *datum {
41 return Err(OperationError::NonCanonical("operation outcome"));
42 }
43 Ok(value)
44 }
45 pub(super) fn canonical_datum(&self) -> Datum {
46 outcome_datum(&self.operation, &self.outcome)
47 }
48}
49
50#[derive(Clone, Debug, PartialEq, Eq)]
52pub struct OperationLifecycleRecord {
53 pub(super) intent: OperationIntent,
54 pub(super) grant: OperationGrant,
55 pub(super) leases: Vec<OperationLease>,
56 pub(super) attempts: Vec<OperationAttempt>,
57 pub(super) dispatches: Vec<FencedDispatch>,
58 pub(super) receipts: Vec<LifecycleReceipt>,
59 pub(super) observations: Vec<OperationObservation>,
60 pub(super) outcomes: Vec<IdentifiedOutcome>,
61 pub(super) last_step: OperationStep,
62}
63
64impl OperationLifecycleRecord {
65 pub const fn intent(&self) -> &OperationIntent {
67 &self.intent
68 }
69 pub const fn grant(&self) -> &OperationGrant {
71 &self.grant
72 }
73 pub fn leases(&self) -> &[OperationLease] {
75 &self.leases
76 }
77 pub fn attempts(&self) -> &[OperationAttempt] {
79 &self.attempts
80 }
81 pub fn dispatches(&self) -> &[FencedDispatch] {
83 &self.dispatches
84 }
85 pub fn receipts(&self) -> &[LifecycleReceipt] {
87 &self.receipts
88 }
89 pub fn observations(&self) -> &[OperationObservation] {
91 &self.observations
92 }
93 pub fn outcome(&self) -> Option<&OperationOutcome> {
95 self.outcomes.last().map(|value| &value.outcome)
96 }
97 pub fn outcome_id(&self) -> Option<&OperationOutcomeId> {
99 self.outcomes.last().map(|value| &value.id)
100 }
101 pub(super) fn last_step(&self) -> OperationStep {
102 self.last_step
103 }
104}