1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Immutable, lifecycle-safe progress reporting.
// qubit-style: allow coverage-cfg
//!
//! A [`Progress`] operation owns its metric state, timing and reporter.
//! Callers configure stable metadata with [`Metric`] and update dynamic counts
//! through cloneable [`MetricHandle`] values. Every emitted [`Event`] is
//! complete.
//!
//! # Benchmark interpretation
//!
//! Run `cargo bench --bench progress_bench -- --noplot` to compare complete
//! event delivery, scheduling paths, and concurrent [`MetricHandle`] updates
//! with a mutex-protected counter baseline. The contention benchmarks use
//! Criterion's batched iteration so setup allocation is excluded from the
//! measured update path; worker thread creation and joining remain part of the
//! workload. Throughput is reported in elements per second for 2,048 updates
//! per worker across 1, 2, 4, 8, 16, 32, and 64 workers.
//!
//! These measurements are workload- and hardware-dependent. The CAS-based
//! metric path is not assumed to beat a mutex at every worker count; measure
//! on target hardware before changing the synchronization strategy or adding
//! backoff, yielding, or sharded counters.
//!
//! # Examples
//!
//! ```
//! use qubit_progress::{Metric, Progress, TextReporter};
//!
//! let reporter = std::sync::Arc::new(TextReporter::new(Vec::new()));
//! let progress = Progress::builder_arc(reporter)
//! .metric(Metric::new("tasks", "Tasks").total(1))
//! .start()?;
//! let tasks = progress.metric("tasks").expect("configured metric must exist");
//! tasks.start(1)?;
//! tasks.succeed(1)?;
//! progress.finish()?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
pub use AutoReporter;
pub use AutoReporterStatus;
pub use ProgressNotifier;
pub use AutoReporterError;
pub use CompletionError;
pub use ConfigurationError;
pub use DeliveryError;
pub use EmissionError;
pub use FinishError;
pub use MetricError;
pub use RecoverableFinishError;
pub use ReporterError;
pub use StartError;
pub use TerminalError;
pub use WorkerPanic;
pub use __coverage_event_serde;
pub use Event;
pub use Phase;
pub use __coverage_internal;
pub use OperationLifecycle;
pub use Metric;
pub use MetricDelta;
pub use MetricHandle;
pub use MetricSnapshot;
pub use OperationAttributes;
pub use __coverage_progress_edges;
pub use Progress;
pub use ProgressBuilder;
pub use JsonLinesReporter;
pub use LogReporter;
pub use NoopReporter;
pub use Reporter;
pub use TextReporter;
pub use Stage;