sim_lib_view_agent/
run.rs1use std::collections::{BTreeMap, BTreeSet};
9
10use sim_kernel::Symbol;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum NodeStatus {
15 Idle,
17 Running,
19 Ok,
21 Error,
23}
24
25impl NodeStatus {
26 pub fn token(self) -> &'static str {
28 match self {
29 NodeStatus::Idle => "idle",
30 NodeStatus::Running => "running",
31 NodeStatus::Ok => "ok",
32 NodeStatus::Error => "error",
33 }
34 }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
39pub struct RunEvent {
40 pub at: u64,
42 pub node: Symbol,
44 pub kind: Symbol,
46 pub message: String,
48 pub edge: Option<(Symbol, Symbol)>,
50}
51
52impl RunEvent {
53 pub fn node(at: u64, node: &str, kind: &str, message: &str) -> Self {
55 Self {
56 at,
57 node: Symbol::new(node),
58 kind: Symbol::new(kind),
59 message: message.to_owned(),
60 edge: None,
61 }
62 }
63
64 pub fn route(at: u64, from: &str, to: &str) -> Self {
66 Self {
67 at,
68 node: Symbol::new(from),
69 kind: Symbol::new("route"),
70 message: format!("{from} -> {to}"),
71 edge: Some((Symbol::new(from), Symbol::new(to))),
72 }
73 }
74}
75
76#[derive(Clone, Debug, Default)]
78pub struct RunState {
79 pub statuses: BTreeMap<Symbol, NodeStatus>,
81 pub counters: BTreeMap<Symbol, u64>,
83 pub events: Vec<RunEvent>,
85 pub live_edges: BTreeSet<(Symbol, Symbol)>,
87}
88
89impl RunState {
90 pub fn new() -> Self {
92 Self::default()
93 }
94
95 pub fn apply_event(&mut self, event: RunEvent) {
97 *self.counters.entry(event.node.clone()).or_insert(0) += 1;
98 match &*event.kind.name {
99 "start" => {
100 self.statuses
101 .insert(event.node.clone(), NodeStatus::Running);
102 }
103 "ok" => {
104 self.statuses.insert(event.node.clone(), NodeStatus::Ok);
105 }
106 "error" => {
107 self.statuses.insert(event.node.clone(), NodeStatus::Error);
108 }
109 "route" => {
110 if let Some(edge) = &event.edge {
111 self.live_edges.insert(edge.clone());
112 }
113 }
114 _ => {}
115 }
116 self.events.push(event);
117 }
118
119 pub fn status(&self, node: &Symbol) -> NodeStatus {
121 self.statuses.get(node).copied().unwrap_or(NodeStatus::Idle)
122 }
123
124 pub fn count(&self, node: &Symbol) -> u64 {
126 self.counters.get(node).copied().unwrap_or(0)
127 }
128
129 pub fn edge_live(&self, from: &Symbol, to: &Symbol) -> bool {
131 self.live_edges.contains(&(from.clone(), to.clone()))
132 }
133
134 pub fn events_for(&self, node: &Symbol) -> Vec<&RunEvent> {
136 self.events
137 .iter()
138 .filter(|event| &event.node == node)
139 .collect()
140 }
141}