use serde::Serialize;
use serde_json::{json, Value};
use std::time::Instant;
#[derive(Debug, Clone)]
pub enum MarkerTiming {
Instant(Instant),
Interval(Instant, Instant),
IntervalStart(Instant),
IntervalEnd(Instant),
}
pub trait ProfilerMarker {
const MARKER_TYPE_NAME: &'static str;
fn schema() -> MarkerSchema;
fn json_marker_data(&self) -> Value;
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MarkerSchema {
#[serde(rename = "name")]
pub type_name: &'static str,
#[serde(rename = "display")]
pub locations: Vec<MarkerLocation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chart_label: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tooltip_label: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub table_label: Option<&'static str>,
#[serde(rename = "data")]
pub fields: Vec<MarkerSchemaField>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum MarkerLocation {
MarkerChart,
MarkerTable,
TimelineOverview,
TimelineMemory,
TimelineIPC,
#[serde(rename = "timeline-fileio")]
TimelineFileIO,
StackChart,
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum MarkerSchemaField {
Static(MarkerStaticField),
Dynamic(MarkerDynamicField),
}
#[derive(Debug, Clone, Serialize)]
pub struct MarkerStaticField {
pub label: &'static str,
pub value: &'static str,
}
#[derive(Debug, Clone, Serialize)]
pub struct MarkerDynamicField {
pub key: &'static str,
#[serde(skip_serializing_if = "str::is_empty")]
pub label: &'static str,
pub format: MarkerFieldFormat,
#[serde(skip_serializing_if = "Option::is_none")]
pub searchable: Option<bool>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum MarkerFieldFormat {
Url,
FilePath,
String,
Duration,
Time,
Seconds, Milliseconds, Microseconds, Nanoseconds,
Bytes,
Percentage,
Integer,
Decimal,
}
#[derive(Debug, Clone)]
pub struct TracingMarker();
impl ProfilerMarker for TracingMarker {
const MARKER_TYPE_NAME: &'static str = "tracing";
fn json_marker_data(&self) -> Value {
json!({
"type": Self::MARKER_TYPE_NAME,
})
}
fn schema() -> MarkerSchema {
MarkerSchema {
type_name: Self::MARKER_TYPE_NAME,
locations: vec![
MarkerLocation::MarkerChart,
MarkerLocation::MarkerTable,
MarkerLocation::TimelineOverview,
],
chart_label: None,
tooltip_label: None,
table_label: None,
fields: vec![],
}
}
}
#[derive(Debug, Clone)]
pub struct TextMarker(pub String);
impl ProfilerMarker for TextMarker {
const MARKER_TYPE_NAME: &'static str = "Text";
fn json_marker_data(&self) -> Value {
json!({
"type": Self::MARKER_TYPE_NAME,
"name": self.0
})
}
fn schema() -> MarkerSchema {
MarkerSchema {
type_name: Self::MARKER_TYPE_NAME,
locations: vec![MarkerLocation::MarkerChart, MarkerLocation::MarkerTable],
chart_label: Some("{marker.data.name}"),
tooltip_label: None,
table_label: Some("{marker.name} - {marker.data.name}"),
fields: vec![MarkerSchemaField::Dynamic(MarkerDynamicField {
key: "name",
label: "Details",
format: MarkerFieldFormat::String,
searchable: None,
})],
}
}
}