1use std::collections::HashMap;
4
5use libpetri_event::net_event::NetEvent;
6
7use crate::debug_response::NetEventInfo;
8
9pub fn to_event_info(event: &NetEvent) -> NetEventInfo {
11 match event {
12 NetEvent::ExecutionStarted {
13 net_name,
14 timestamp,
15 } => NetEventInfo {
16 event_type: "ExecutionStarted".into(),
17 timestamp: format_timestamp(*timestamp),
18 transition_name: None,
19 place_name: None,
20 details: HashMap::from([(
21 "netName".into(),
22 serde_json::Value::String(net_name.to_string()),
23 )]),
24 },
25 NetEvent::ExecutionCompleted {
26 net_name,
27 timestamp,
28 } => NetEventInfo {
29 event_type: "ExecutionCompleted".into(),
30 timestamp: format_timestamp(*timestamp),
31 transition_name: None,
32 place_name: None,
33 details: HashMap::from([(
34 "netName".into(),
35 serde_json::Value::String(net_name.to_string()),
36 )]),
37 },
38 NetEvent::TransitionEnabled {
39 transition_name,
40 timestamp,
41 } => NetEventInfo {
42 event_type: "TransitionEnabled".into(),
43 timestamp: format_timestamp(*timestamp),
44 transition_name: Some(transition_name.to_string()),
45 place_name: None,
46 details: HashMap::new(),
47 },
48 NetEvent::TransitionClockRestarted {
49 transition_name,
50 timestamp,
51 } => NetEventInfo {
52 event_type: "TransitionClockRestarted".into(),
53 timestamp: format_timestamp(*timestamp),
54 transition_name: Some(transition_name.to_string()),
55 place_name: None,
56 details: HashMap::new(),
57 },
58 NetEvent::TransitionStarted {
59 transition_name,
60 timestamp,
61 } => NetEventInfo {
62 event_type: "TransitionStarted".into(),
63 timestamp: format_timestamp(*timestamp),
64 transition_name: Some(transition_name.to_string()),
65 place_name: None,
66 details: HashMap::new(),
67 },
68 NetEvent::TransitionCompleted {
69 transition_name,
70 timestamp,
71 } => NetEventInfo {
72 event_type: "TransitionCompleted".into(),
73 timestamp: format_timestamp(*timestamp),
74 transition_name: Some(transition_name.to_string()),
75 place_name: None,
76 details: HashMap::new(),
77 },
78 NetEvent::TransitionFailed {
79 transition_name,
80 error,
81 timestamp,
82 } => NetEventInfo {
83 event_type: "TransitionFailed".into(),
84 timestamp: format_timestamp(*timestamp),
85 transition_name: Some(transition_name.to_string()),
86 place_name: None,
87 details: HashMap::from([(
88 "errorMessage".into(),
89 serde_json::Value::String(error.clone()),
90 )]),
91 },
92 NetEvent::TransitionTimedOut {
93 transition_name,
94 timestamp,
95 } => NetEventInfo {
96 event_type: "TransitionTimedOut".into(),
97 timestamp: format_timestamp(*timestamp),
98 transition_name: Some(transition_name.to_string()),
99 place_name: None,
100 details: HashMap::new(),
101 },
102 NetEvent::ActionTimedOut {
103 transition_name,
104 timeout_ms,
105 timestamp,
106 } => NetEventInfo {
107 event_type: "ActionTimedOut".into(),
108 timestamp: format_timestamp(*timestamp),
109 transition_name: Some(transition_name.to_string()),
110 place_name: None,
111 details: HashMap::from([("timeoutMs".into(), serde_json::json!(*timeout_ms))]),
112 },
113 NetEvent::TokenAdded {
114 place_name,
115 timestamp,
116 } => NetEventInfo {
117 event_type: "TokenAdded".into(),
118 timestamp: format_timestamp(*timestamp),
119 transition_name: None,
120 place_name: Some(place_name.to_string()),
121 details: HashMap::new(),
122 },
123 NetEvent::TokenRemoved {
124 place_name,
125 timestamp,
126 } => NetEventInfo {
127 event_type: "TokenRemoved".into(),
128 timestamp: format_timestamp(*timestamp),
129 transition_name: None,
130 place_name: Some(place_name.to_string()),
131 details: HashMap::new(),
132 },
133 NetEvent::LogMessage {
134 transition_name,
135 level,
136 message,
137 timestamp,
138 } => NetEventInfo {
139 event_type: "LogMessage".into(),
140 timestamp: format_timestamp(*timestamp),
141 transition_name: Some(transition_name.to_string()),
142 place_name: None,
143 details: HashMap::from([
144 ("level".into(), serde_json::Value::String(level.clone())),
145 ("message".into(), serde_json::Value::String(message.clone())),
146 ]),
147 },
148 NetEvent::MarkingSnapshot { marking, timestamp } => {
149 let marking_map: HashMap<String, usize> =
150 marking.iter().map(|(k, v)| (k.to_string(), *v)).collect();
151 NetEventInfo {
152 event_type: "MarkingSnapshot".into(),
153 timestamp: format_timestamp(*timestamp),
154 transition_name: None,
155 place_name: None,
156 details: HashMap::from([("marking".into(), serde_json::json!(marking_map))]),
157 }
158 }
159 }
160}
161
162fn format_timestamp(ms: u64) -> String {
165 ms.to_string()
166}
167
168pub fn extract_transition_name(event: &NetEvent) -> Option<&str> {
170 event.transition_name()
171}
172
173pub fn extract_place_name(event: &NetEvent) -> Option<&str> {
175 match event {
176 NetEvent::TokenAdded { place_name, .. } | NetEvent::TokenRemoved { place_name, .. } => {
177 Some(place_name)
178 }
179 _ => None,
180 }
181}
182
183pub fn event_type_name(event: &NetEvent) -> &'static str {
185 match event {
186 NetEvent::ExecutionStarted { .. } => "ExecutionStarted",
187 NetEvent::ExecutionCompleted { .. } => "ExecutionCompleted",
188 NetEvent::TransitionEnabled { .. } => "TransitionEnabled",
189 NetEvent::TransitionClockRestarted { .. } => "TransitionClockRestarted",
190 NetEvent::TransitionStarted { .. } => "TransitionStarted",
191 NetEvent::TransitionCompleted { .. } => "TransitionCompleted",
192 NetEvent::TransitionFailed { .. } => "TransitionFailed",
193 NetEvent::TransitionTimedOut { .. } => "TransitionTimedOut",
194 NetEvent::ActionTimedOut { .. } => "ActionTimedOut",
195 NetEvent::TokenAdded { .. } => "TokenAdded",
196 NetEvent::TokenRemoved { .. } => "TokenRemoved",
197 NetEvent::LogMessage { .. } => "LogMessage",
198 NetEvent::MarkingSnapshot { .. } => "MarkingSnapshot",
199 }
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205 use std::sync::Arc;
206
207 #[test]
208 fn convert_execution_started() {
209 let event = NetEvent::ExecutionStarted {
210 net_name: Arc::from("test"),
211 timestamp: 1000,
212 };
213 let info = to_event_info(&event);
214 assert_eq!(info.event_type, "ExecutionStarted");
215 assert_eq!(info.timestamp, "1000");
216 assert!(info.transition_name.is_none());
217 assert_eq!(info.details["netName"], "test");
218 }
219
220 #[test]
221 fn convert_transition_started() {
222 let event = NetEvent::TransitionStarted {
223 transition_name: Arc::from("t1"),
224 timestamp: 2000,
225 };
226 let info = to_event_info(&event);
227 assert_eq!(info.event_type, "TransitionStarted");
228 assert_eq!(info.transition_name.as_deref(), Some("t1"));
229 }
230
231 #[test]
232 fn convert_token_added() {
233 let event = NetEvent::TokenAdded {
234 place_name: Arc::from("p1"),
235 timestamp: 3000,
236 };
237 let info = to_event_info(&event);
238 assert_eq!(info.event_type, "TokenAdded");
239 assert_eq!(info.place_name.as_deref(), Some("p1"));
240 }
241
242 #[test]
243 fn convert_all_variants() {
244 let events = vec![
245 NetEvent::ExecutionStarted {
246 net_name: Arc::from("n"),
247 timestamp: 0,
248 },
249 NetEvent::ExecutionCompleted {
250 net_name: Arc::from("n"),
251 timestamp: 1,
252 },
253 NetEvent::TransitionEnabled {
254 transition_name: Arc::from("t"),
255 timestamp: 2,
256 },
257 NetEvent::TransitionClockRestarted {
258 transition_name: Arc::from("t"),
259 timestamp: 3,
260 },
261 NetEvent::TransitionStarted {
262 transition_name: Arc::from("t"),
263 timestamp: 4,
264 },
265 NetEvent::TransitionCompleted {
266 transition_name: Arc::from("t"),
267 timestamp: 5,
268 },
269 NetEvent::TransitionFailed {
270 transition_name: Arc::from("t"),
271 error: "err".into(),
272 timestamp: 6,
273 },
274 NetEvent::TransitionTimedOut {
275 transition_name: Arc::from("t"),
276 timestamp: 7,
277 },
278 NetEvent::ActionTimedOut {
279 transition_name: Arc::from("t"),
280 timeout_ms: 100,
281 timestamp: 8,
282 },
283 NetEvent::TokenAdded {
284 place_name: Arc::from("p"),
285 timestamp: 9,
286 },
287 NetEvent::TokenRemoved {
288 place_name: Arc::from("p"),
289 timestamp: 10,
290 },
291 NetEvent::LogMessage {
292 transition_name: Arc::from("t"),
293 level: "INFO".into(),
294 message: "msg".into(),
295 timestamp: 11,
296 },
297 NetEvent::MarkingSnapshot {
298 marking: HashMap::from([(Arc::from("p"), 1)]),
299 timestamp: 12,
300 },
301 ];
302 for event in &events {
303 let info = to_event_info(event);
304 let _json = serde_json::to_string(&info).unwrap();
306 }
307 }
308
309 #[test]
310 fn event_type_names() {
311 let event = NetEvent::TransitionStarted {
312 transition_name: Arc::from("t"),
313 timestamp: 0,
314 };
315 assert_eq!(event_type_name(&event), "TransitionStarted");
316 }
317}