use crate::span::{Span, Status};
use serde_json::{json, Value};
pub fn to_chrome_trace(spans: &[Span]) -> Value {
let mut tracks: Vec<&str> = Vec::new();
for s in spans {
if !tracks.iter().any(|&t| t == s.track) {
tracks.push(s.track.as_str());
}
}
let pid_of = |track: &str| tracks.iter().position(|&x| x == track).unwrap() as i64;
let mut events: Vec<Value> = Vec::new();
for (i, t) in tracks.iter().enumerate() {
events.push(process_name_event(t, i as i64));
}
for s in spans {
events.push(span_event(s, pid_of(&s.track)));
}
json!({ "traceEvents": events, "displayTimeUnit": "ms" })
}
pub fn process_name_event(track: &str, pid: i64) -> Value {
json!({ "ph": "M", "name": "process_name", "pid": pid, "tid": 0, "args": { "name": track } })
}
pub fn span_event(s: &Span, pid: i64) -> Value {
let mut ev = json!({
"ph": "X",
"name": s.name,
"cat": s.category.as_str(),
"ts": s.start_us,
"dur": s.dur_us,
"pid": pid,
"tid": s.lane,
"args": { "status": s.status.as_str() },
});
if let Some(colour) = colour_of(&s.status) {
ev["cname"] = json!(colour);
}
if !s.args.is_empty() {
let a = ev["args"].as_object_mut().unwrap();
for (k, v) in &s.args {
a.insert(k.clone(), json!(v));
}
}
ev
}
fn colour_of(status: &Status) -> Option<&'static str> {
match status {
Status::Success => None,
Status::Failed => Some("terrible"), Status::Incomplete => Some("bad"), Status::Skipped => Some("grey"),
}
}