use std::collections::HashMap;
use libpetri_event::net_event::NetEvent;
use crate::debug_response::NetEventInfo;
pub fn to_event_info(event: &NetEvent) -> NetEventInfo {
match event {
NetEvent::ExecutionStarted {
net_name,
timestamp,
} => NetEventInfo {
event_type: "ExecutionStarted".into(),
timestamp: format_timestamp(*timestamp),
transition_name: None,
place_name: None,
details: HashMap::from([(
"netName".into(),
serde_json::Value::String(net_name.to_string()),
)]),
},
NetEvent::ExecutionCompleted {
net_name,
timestamp,
} => NetEventInfo {
event_type: "ExecutionCompleted".into(),
timestamp: format_timestamp(*timestamp),
transition_name: None,
place_name: None,
details: HashMap::from([(
"netName".into(),
serde_json::Value::String(net_name.to_string()),
)]),
},
NetEvent::TransitionEnabled {
transition_name,
timestamp,
} => NetEventInfo {
event_type: "TransitionEnabled".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::new(),
},
NetEvent::TransitionClockRestarted {
transition_name,
timestamp,
} => NetEventInfo {
event_type: "TransitionClockRestarted".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::new(),
},
NetEvent::TransitionStarted {
transition_name,
timestamp,
} => NetEventInfo {
event_type: "TransitionStarted".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::new(),
},
NetEvent::TransitionCompleted {
transition_name,
timestamp,
} => NetEventInfo {
event_type: "TransitionCompleted".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::new(),
},
NetEvent::TransitionFailed {
transition_name,
error,
timestamp,
} => NetEventInfo {
event_type: "TransitionFailed".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::from([(
"errorMessage".into(),
serde_json::Value::String(error.clone()),
)]),
},
NetEvent::TransitionTimedOut {
transition_name,
timestamp,
} => NetEventInfo {
event_type: "TransitionTimedOut".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::new(),
},
NetEvent::ActionTimedOut {
transition_name,
timeout_ms,
timestamp,
} => NetEventInfo {
event_type: "ActionTimedOut".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::from([("timeoutMs".into(), serde_json::json!(*timeout_ms))]),
},
NetEvent::TokenAdded {
place_name,
timestamp,
} => NetEventInfo {
event_type: "TokenAdded".into(),
timestamp: format_timestamp(*timestamp),
transition_name: None,
place_name: Some(place_name.to_string()),
details: HashMap::new(),
},
NetEvent::TokenRemoved {
place_name,
timestamp,
} => NetEventInfo {
event_type: "TokenRemoved".into(),
timestamp: format_timestamp(*timestamp),
transition_name: None,
place_name: Some(place_name.to_string()),
details: HashMap::new(),
},
NetEvent::LogMessage {
transition_name,
level,
message,
timestamp,
} => NetEventInfo {
event_type: "LogMessage".into(),
timestamp: format_timestamp(*timestamp),
transition_name: Some(transition_name.to_string()),
place_name: None,
details: HashMap::from([
("level".into(), serde_json::Value::String(level.clone())),
("message".into(), serde_json::Value::String(message.clone())),
]),
},
NetEvent::MarkingSnapshot { marking, timestamp } => {
let marking_map: HashMap<String, usize> =
marking.iter().map(|(k, v)| (k.to_string(), *v)).collect();
NetEventInfo {
event_type: "MarkingSnapshot".into(),
timestamp: format_timestamp(*timestamp),
transition_name: None,
place_name: None,
details: HashMap::from([("marking".into(), serde_json::json!(marking_map))]),
}
}
}
}
fn format_timestamp(ms: u64) -> String {
ms.to_string()
}
pub fn extract_transition_name(event: &NetEvent) -> Option<&str> {
event.transition_name()
}
pub fn extract_place_name(event: &NetEvent) -> Option<&str> {
match event {
NetEvent::TokenAdded { place_name, .. } | NetEvent::TokenRemoved { place_name, .. } => {
Some(place_name)
}
_ => None,
}
}
pub fn event_type_name(event: &NetEvent) -> &'static str {
match event {
NetEvent::ExecutionStarted { .. } => "ExecutionStarted",
NetEvent::ExecutionCompleted { .. } => "ExecutionCompleted",
NetEvent::TransitionEnabled { .. } => "TransitionEnabled",
NetEvent::TransitionClockRestarted { .. } => "TransitionClockRestarted",
NetEvent::TransitionStarted { .. } => "TransitionStarted",
NetEvent::TransitionCompleted { .. } => "TransitionCompleted",
NetEvent::TransitionFailed { .. } => "TransitionFailed",
NetEvent::TransitionTimedOut { .. } => "TransitionTimedOut",
NetEvent::ActionTimedOut { .. } => "ActionTimedOut",
NetEvent::TokenAdded { .. } => "TokenAdded",
NetEvent::TokenRemoved { .. } => "TokenRemoved",
NetEvent::LogMessage { .. } => "LogMessage",
NetEvent::MarkingSnapshot { .. } => "MarkingSnapshot",
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn convert_execution_started() {
let event = NetEvent::ExecutionStarted {
net_name: Arc::from("test"),
timestamp: 1000,
};
let info = to_event_info(&event);
assert_eq!(info.event_type, "ExecutionStarted");
assert_eq!(info.timestamp, "1000");
assert!(info.transition_name.is_none());
assert_eq!(info.details["netName"], "test");
}
#[test]
fn convert_transition_started() {
let event = NetEvent::TransitionStarted {
transition_name: Arc::from("t1"),
timestamp: 2000,
};
let info = to_event_info(&event);
assert_eq!(info.event_type, "TransitionStarted");
assert_eq!(info.transition_name.as_deref(), Some("t1"));
}
#[test]
fn convert_token_added() {
let event = NetEvent::TokenAdded {
place_name: Arc::from("p1"),
timestamp: 3000,
};
let info = to_event_info(&event);
assert_eq!(info.event_type, "TokenAdded");
assert_eq!(info.place_name.as_deref(), Some("p1"));
}
#[test]
fn convert_all_variants() {
let events = vec![
NetEvent::ExecutionStarted {
net_name: Arc::from("n"),
timestamp: 0,
},
NetEvent::ExecutionCompleted {
net_name: Arc::from("n"),
timestamp: 1,
},
NetEvent::TransitionEnabled {
transition_name: Arc::from("t"),
timestamp: 2,
},
NetEvent::TransitionClockRestarted {
transition_name: Arc::from("t"),
timestamp: 3,
},
NetEvent::TransitionStarted {
transition_name: Arc::from("t"),
timestamp: 4,
},
NetEvent::TransitionCompleted {
transition_name: Arc::from("t"),
timestamp: 5,
},
NetEvent::TransitionFailed {
transition_name: Arc::from("t"),
error: "err".into(),
timestamp: 6,
},
NetEvent::TransitionTimedOut {
transition_name: Arc::from("t"),
timestamp: 7,
},
NetEvent::ActionTimedOut {
transition_name: Arc::from("t"),
timeout_ms: 100,
timestamp: 8,
},
NetEvent::TokenAdded {
place_name: Arc::from("p"),
timestamp: 9,
},
NetEvent::TokenRemoved {
place_name: Arc::from("p"),
timestamp: 10,
},
NetEvent::LogMessage {
transition_name: Arc::from("t"),
level: "INFO".into(),
message: "msg".into(),
timestamp: 11,
},
NetEvent::MarkingSnapshot {
marking: HashMap::from([(Arc::from("p"), 1)]),
timestamp: 12,
},
];
for event in &events {
let info = to_event_info(event);
let _json = serde_json::to_string(&info).unwrap();
}
}
#[test]
fn event_type_names() {
let event = NetEvent::TransitionStarted {
transition_name: Arc::from("t"),
timestamp: 0,
};
assert_eq!(event_type_name(&event), "TransitionStarted");
}
}