use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TraceEntry {
pub frame: u64,
pub timestamp_ms: f64,
pub entry_type: TraceEntryType,
pub source: String,
pub target: Option<String>,
}
impl TraceEntry {
pub fn new(
frame: u64,
timestamp_ms: f64,
entry_type: TraceEntryType,
source: impl Into<String>,
) -> Self {
Self {
frame,
timestamp_ms,
entry_type,
source: source.into(),
target: None,
}
}
pub fn with_target(mut self, target: impl Into<String>) -> Self {
self.target = Some(target.into());
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum TraceEntryType {
EventPublished {
event_type: String,
event_id: String,
},
EventDispatched {
event_type: String,
subscriber_count: usize,
},
HookCalled {
hook_name: String,
plugin: String,
args: String,
},
HookCompleted {
hook_name: String,
plugin: String,
duration_ms: f64,
result: HookResult,
},
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum HookResult {
Success,
Error(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trace_entry_creation() {
let entry = TraceEntry::new(
0,
0.0,
TraceEntryType::EventPublished {
event_type: "TestEvent".to_string(),
event_id: "test_1".to_string(),
},
"EventBus",
);
assert_eq!(entry.frame, 0);
assert_eq!(entry.timestamp_ms, 0.0);
assert_eq!(entry.source, "EventBus");
assert!(entry.target.is_none());
}
#[test]
fn test_trace_entry_with_target() {
let entry = TraceEntry::new(
1,
16.0,
TraceEntryType::HookCalled {
hook_name: "on_travel_started".to_string(),
plugin: "WorldMapPlugin".to_string(),
args: "()".to_string(),
},
"WorldMapSystem",
)
.with_target("LogisticsPlugin");
assert_eq!(entry.target, Some("LogisticsPlugin".to_string()));
}
#[test]
fn test_serialization() {
let entry = TraceEntry::new(
0,
0.0,
TraceEntryType::EventPublished {
event_type: "TestEvent".to_string(),
event_id: "test_1".to_string(),
},
"EventBus",
);
let json = serde_json::to_string(&entry).unwrap();
let deserialized: TraceEntry = serde_json::from_str(&json).unwrap();
assert_eq!(entry.frame, deserialized.frame);
assert_eq!(entry.source, deserialized.source);
}
}