Skip to main content

cu_profiler_report/
json.rs

1//! Stable JSON output for machines and CI.
2//!
3//! The schema is the serialized [`Report`]; it is intentionally the same shape
4//! the `inspect` command reads back.
5
6use cu_profiler_core::Result;
7
8use crate::model::Report;
9
10/// Render `report` as pretty-printed JSON.
11///
12/// # Errors
13/// Propagates any serialization failure as [`cu_profiler_core::Error`].
14pub fn render(report: &Report) -> Result<String> {
15    Ok(serde_json::to_string_pretty(report)?)
16}
17
18/// Parse a [`Report`] back from JSON (used by `cu-profiler inspect`).
19///
20/// # Errors
21/// Propagates any deserialization failure.
22pub fn parse(json: &str) -> Result<Report> {
23    Ok(serde_json::from_str(json)?)
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use cu_profiler_core::Profiler;
30    use cu_profiler_core::backend::RecordedLogsBackend;
31    use cu_profiler_core::metadata::RunMetadata;
32    use cu_profiler_core::scenario::Scenario;
33
34    #[test]
35    fn json_round_trips() {
36        let mut backend = RecordedLogsBackend::new();
37        backend.insert_blob(
38            "s",
39            "Program P invoke [1]\nProgram P consumed 1000 of 200000 compute units\nProgram P success",
40            true,
41        );
42        let report = Profiler::new().run(
43            &backend,
44            &[Scenario::new("s")],
45            None,
46            RunMetadata::recorded("0.1.0"),
47        );
48        let json = render(&report).unwrap();
49        assert!(json.contains("\"summary\""));
50        assert!(json.contains("\"total_cu\""));
51        let back = parse(&json).unwrap();
52        assert_eq!(report, back);
53    }
54}