simplebench_runtime/
progress.rs

1//! Progress reporting for benchmark execution.
2//!
3//! Emits JSON progress messages to stderr during warmup and sample collection.
4//! The CLI tool parses these to display progress bars.
5
6use serde::Serialize;
7
8/// Progress phase during benchmark execution.
9#[derive(Debug, Clone, Serialize)]
10#[serde(tag = "phase")]
11pub enum ProgressPhase {
12    /// Warmup phase - running iterations to stabilize CPU/cache state.
13    #[serde(rename = "warmup")]
14    Warmup {
15        /// Milliseconds elapsed so far.
16        elapsed_ms: u64,
17        /// Target warmup duration in milliseconds.
18        target_ms: u64,
19    },
20    /// Sample collection phase.
21    #[serde(rename = "samples")]
22    Samples {
23        /// Current sample index (0-based).
24        current: u32,
25        /// Total number of samples to collect.
26        total: u32,
27    },
28    /// Benchmark complete.
29    #[serde(rename = "complete")]
30    Complete,
31}
32
33/// Progress message emitted to stderr during benchmark execution.
34#[derive(Debug, Clone, Serialize)]
35pub struct ProgressMessage<'a> {
36    /// Benchmark name.
37    pub bench: &'a str,
38    /// Current phase and its data.
39    #[serde(flatten)]
40    pub phase: ProgressPhase,
41}
42
43/// Check if progress output is enabled (not suppressed via env var).
44fn progress_enabled() -> bool {
45    std::env::var("SIMPLEBENCH_QUIET").is_err()
46}
47
48/// Emit progress JSON to stderr (non-blocking, fire-and-forget).
49///
50/// Output is wrapped in `{"progress": ...}` envelope to distinguish
51/// from other stderr output (warnings, errors).
52pub fn emit_progress(msg: &ProgressMessage) {
53    if !progress_enabled() {
54        return;
55    }
56
57    // Wrap in {"progress": ...} envelope
58    if let Ok(json) = serde_json::to_string(&serde_json::json!({"progress": msg})) {
59        eprintln!("{}", json);
60    }
61}