wowlab_engine_domain/rotation/
decision_trace.rs1use wowlab_types::sim::{Condition, RotationAction};
2
3#[rustfmt::skip]
4pub use wowlab_engine_ports::{ActionEvaluation, Decision, DecisionTrace, DecisionTraceSink, DecisionTraceTarget, EvaluationStatus, VecSink};
5
6#[derive(Debug)]
8pub struct ActionRecord<'a> {
9 pub list_id: &'a str,
10 pub action_index: usize,
11 pub action: &'a RotationAction,
12 pub outcome: ActionOutcome<'a>,
13}
14
15#[derive(Debug)]
17#[non_exhaustive]
18pub enum ActionOutcome<'a> {
19 Fired,
20 Executed,
21 Rejected { failing: &'a Condition },
22 NotReached,
23 Disabled,
24}
25
26impl ActionOutcome<'_> {
27 #[must_use]
29 pub fn status(&self) -> EvaluationStatus {
30 match self {
31 ActionOutcome::Fired => EvaluationStatus::Fired,
32 ActionOutcome::Executed => EvaluationStatus::Executed,
33 ActionOutcome::Rejected { .. } => EvaluationStatus::Rejected,
34 ActionOutcome::NotReached => EvaluationStatus::NotReached,
35 ActionOutcome::Disabled => EvaluationStatus::Disabled,
36 }
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use googletest::prelude::*;
43 use rstest::rstest;
44
45 use super::*;
46
47 #[gtest]
48 #[rstest]
49 #[case(ActionOutcome::Fired, EvaluationStatus::Fired)]
50 #[case(ActionOutcome::Executed, EvaluationStatus::Executed)]
51 #[case(ActionOutcome::NotReached, EvaluationStatus::NotReached)]
52 #[case(ActionOutcome::Disabled, EvaluationStatus::Disabled)]
53 fn action_outcome_status_maps_each_variant(
54 #[case] outcome: ActionOutcome<'_>,
55 #[case] expected: EvaluationStatus,
56 ) -> Result<()> {
57 verify_that!(outcome.status(), eq(expected))
58 }
59
60 #[gtest]
61 fn rejected_outcome_maps_to_rejected_status() -> Result<()> {
62 let cond = Condition::Bool { value: true };
63 let outcome = ActionOutcome::Rejected { failing: &cond };
64
65 verify_that!(outcome.status(), eq(EvaluationStatus::Rejected))
66 }
67}