1use super::catalog::FullProfile;
4use anyhow::Result;
5use std::path::Path;
6
7pub fn export_json(profile: &FullProfile, path: &Path) -> Result<()> {
9 let json = serde_json::to_string_pretty(profile)?;
10 std::fs::write(path, json)?;
11 Ok(())
12}
13
14pub fn load_json(path: &Path) -> Result<FullProfile> {
16 let content = std::fs::read_to_string(path)?;
17 let profile: FullProfile = serde_json::from_str(&content)?;
18 Ok(profile)
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24 use crate::metrics::catalog::{ThroughputMetrics, TimingMetrics};
25
26 #[test]
27 fn test_export_load_roundtrip() {
28 let profile = FullProfile {
29 version: "2.0".to_string(),
30 timestamp: "2026-04-04T12:00:00Z".to_string(),
31 timing: TimingMetrics {
32 wall_clock_time_us: 23.2,
33 samples: 50,
34 ..Default::default()
35 },
36 throughput: ThroughputMetrics {
37 tflops: 11.6,
38 ..Default::default()
39 },
40 ..Default::default()
41 };
42
43 let dir = tempfile::tempdir().unwrap();
44 let path = dir.path().join("test_profile.json");
45 export_json(&profile, &path).unwrap();
46 let loaded = load_json(&path).unwrap();
47 assert_eq!(loaded.version, "2.0");
48 assert!((loaded.timing.wall_clock_time_us - 23.2).abs() < 0.01);
49 }
50
51 #[test]
54 fn test_json_load_speed() {
55 let profile = FullProfile {
56 version: "2.0".to_string(),
57 ..Default::default()
58 };
59 let dir = tempfile::tempdir().unwrap();
60 let path = dir.path().join("speed_test.json");
61 export_json(&profile, &path).unwrap();
62
63 let start = std::time::Instant::now();
64 let _ = load_json(&path).unwrap();
65 let _ = load_json(&path).unwrap();
66 let elapsed = start.elapsed();
67 assert!(
68 elapsed.as_millis() < 100,
69 "Loading two JSONs took {}ms (should be <100ms)",
70 elapsed.as_millis()
71 );
72 }
73}