made_core/value_objects/ceremony_outcome.rs
1//! [`CeremonyOutcome`] — the terminal result of a ceremony run.
2//!
3//! A ceremony driven to a stop ends in exactly one of these. Unlike a
4//! step's [`StepStatus`](super::StepStatus), this names *why the whole
5//! ceremony stopped*: it completed, a step failed, no transition could
6//! fire, the safety iteration cap was hit, or the instance already
7//! existed. Adapter-shaped aborts (persistence/transport errors) are not
8//! outcomes — they surface as errors, not as a recorded end-state.
9
10/// How a ceremony run terminated.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum CeremonyOutcome {
13 /// Reached a terminal state — the ceremony finished.
14 Completed,
15 /// A step did not complete successfully and aborted the run.
16 StepFailed,
17 /// No transition out of the current state was satisfiable (a guard
18 /// deadlock or a missing event).
19 NoTransition,
20 /// The transition safety cap was hit without reaching a terminal
21 /// state.
22 IterationLimit,
23 /// An instance with the same id already existed; the run was rejected.
24 AlreadyExists,
25}
26
27impl CeremonyOutcome {
28 /// Stable, low-cardinality label value for metrics exposition. Part of
29 /// the metric contract; dashboards and alerts match on it.
30 #[must_use]
31 pub const fn as_label(self) -> &'static str {
32 match self {
33 Self::Completed => "completed",
34 Self::StepFailed => "step_failed",
35 Self::NoTransition => "no_transition",
36 Self::IterationLimit => "iteration_limit",
37 Self::AlreadyExists => "already_exists",
38 }
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn labels_are_distinct_and_stable() {
48 let all = [
49 CeremonyOutcome::Completed,
50 CeremonyOutcome::StepFailed,
51 CeremonyOutcome::NoTransition,
52 CeremonyOutcome::IterationLimit,
53 CeremonyOutcome::AlreadyExists,
54 ];
55 let labels: std::collections::BTreeSet<&str> =
56 all.iter().map(|outcome| outcome.as_label()).collect();
57 assert_eq!(labels.len(), all.len());
58 }
59}