qubit_progress/model/progress_event_builder.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::time::Duration;
11
12use super::{
13 ProgressCounters,
14 ProgressEvent,
15 ProgressPhase,
16 ProgressStage,
17};
18
19/// Builder for [`ProgressEvent`].
20///
21/// The builder keeps the common path compact by letting callers configure
22/// phase, counters, optional stage information, and elapsed time in a single
23/// chain.
24#[derive(Debug, Clone, PartialEq)]
25pub struct ProgressEventBuilder {
26 /// Lifecycle phase of the event being built.
27 pub(crate) phase: ProgressPhase,
28 /// Generic counters for the event being built.
29 pub(crate) counters: ProgressCounters,
30 /// Optional current stage.
31 pub(crate) stage: Option<ProgressStage>,
32 /// Monotonic elapsed duration.
33 pub(crate) elapsed: Duration,
34}
35
36impl ProgressEventBuilder {
37 /// Creates a builder with default running progress state.
38 ///
39 /// # Returns
40 ///
41 /// A builder whose phase is [`ProgressPhase::Running`], elapsed duration is
42 /// zero, total count is unknown, and all counters are zero.
43 #[inline]
44 pub const fn new() -> Self {
45 Self {
46 phase: ProgressPhase::Running,
47 counters: ProgressCounters::new(None),
48 stage: None,
49 elapsed: Duration::ZERO,
50 }
51 }
52
53 /// Configures the lifecycle phase.
54 ///
55 /// # Parameters
56 ///
57 /// * `phase` - Lifecycle phase to report.
58 ///
59 /// # Returns
60 ///
61 /// This builder with `phase` recorded.
62 #[inline]
63 pub const fn phase(mut self, phase: ProgressPhase) -> Self {
64 self.phase = phase;
65 self
66 }
67
68 /// Configures the event as started.
69 ///
70 /// # Returns
71 ///
72 /// This builder with [`ProgressPhase::Started`].
73 #[inline]
74 pub const fn started(self) -> Self {
75 self.phase(ProgressPhase::Started)
76 }
77
78 /// Configures the event as running.
79 ///
80 /// # Returns
81 ///
82 /// This builder with [`ProgressPhase::Running`].
83 #[inline]
84 pub const fn running(self) -> Self {
85 self.phase(ProgressPhase::Running)
86 }
87
88 /// Configures the event as finished.
89 ///
90 /// # Returns
91 ///
92 /// This builder with [`ProgressPhase::Finished`].
93 #[inline]
94 pub const fn finished(self) -> Self {
95 self.phase(ProgressPhase::Finished)
96 }
97
98 /// Configures the event as failed.
99 ///
100 /// # Returns
101 ///
102 /// This builder with [`ProgressPhase::Failed`].
103 #[inline]
104 pub const fn failed(self) -> Self {
105 self.phase(ProgressPhase::Failed)
106 }
107
108 /// Configures the event as canceled.
109 ///
110 /// # Returns
111 ///
112 /// This builder with [`ProgressPhase::Canceled`].
113 #[inline]
114 pub const fn canceled(self) -> Self {
115 self.phase(ProgressPhase::Canceled)
116 }
117
118 /// Replaces the current counter set.
119 ///
120 /// # Parameters
121 ///
122 /// * `counters` - Complete counter set to carry in the built event.
123 ///
124 /// # Returns
125 ///
126 /// This builder with `counters` recorded.
127 #[inline]
128 pub const fn counters(mut self, counters: ProgressCounters) -> Self {
129 self.counters = counters;
130 self
131 }
132
133 /// Configures a known total work-unit count.
134 ///
135 /// # Parameters
136 ///
137 /// * `total_count` - Total number of work units.
138 ///
139 /// # Returns
140 ///
141 /// This builder with a known total count.
142 #[inline]
143 pub const fn total(mut self, total_count: usize) -> Self {
144 self.counters = self.counters.with_total_count(Some(total_count));
145 self
146 }
147
148 /// Configures the event as unknown-total progress.
149 ///
150 /// # Returns
151 ///
152 /// This builder with no total count.
153 #[inline]
154 pub const fn unknown_total(mut self) -> Self {
155 self.counters = self.counters.with_total_count(None);
156 self
157 }
158
159 /// Configures the completed work-unit count.
160 ///
161 /// # Parameters
162 ///
163 /// * `completed_count` - Number of completed work units.
164 ///
165 /// # Returns
166 ///
167 /// This builder with `completed_count` recorded.
168 #[inline]
169 pub const fn completed(mut self, completed_count: usize) -> Self {
170 self.counters = self.counters.with_completed_count(completed_count);
171 self
172 }
173
174 /// Configures the active work-unit count.
175 ///
176 /// # Parameters
177 ///
178 /// * `active_count` - Number of currently active work units.
179 ///
180 /// # Returns
181 ///
182 /// This builder with `active_count` recorded.
183 #[inline]
184 pub const fn active(mut self, active_count: usize) -> Self {
185 self.counters = self.counters.with_active_count(active_count);
186 self
187 }
188
189 /// Configures the successful work-unit count.
190 ///
191 /// # Parameters
192 ///
193 /// * `succeeded_count` - Number of successful work units.
194 ///
195 /// # Returns
196 ///
197 /// This builder with `succeeded_count` recorded.
198 #[inline]
199 pub const fn succeeded(mut self, succeeded_count: usize) -> Self {
200 self.counters = self.counters.with_succeeded_count(succeeded_count);
201 self
202 }
203
204 /// Configures the failed work-unit count.
205 ///
206 /// # Parameters
207 ///
208 /// * `failed_count` - Number of failed work units.
209 ///
210 /// # Returns
211 ///
212 /// This builder with `failed_count` recorded.
213 #[inline]
214 pub const fn failed_count(mut self, failed_count: usize) -> Self {
215 self.counters = self.counters.with_failed_count(failed_count);
216 self
217 }
218
219 /// Configures the current stage.
220 ///
221 /// # Parameters
222 ///
223 /// * `stage` - Stage metadata to carry in the built event.
224 ///
225 /// # Returns
226 ///
227 /// This builder with `stage` recorded.
228 #[inline]
229 pub fn stage(mut self, stage: ProgressStage) -> Self {
230 self.stage = Some(stage);
231 self
232 }
233
234 /// Configures the current stage from an id and display name.
235 ///
236 /// # Parameters
237 ///
238 /// * `id` - Stable machine-readable stage identifier.
239 /// * `name` - Human-readable stage name.
240 ///
241 /// # Returns
242 ///
243 /// This builder with a stage created from `id` and `name`.
244 #[inline]
245 pub fn stage_named(self, id: &str, name: &str) -> Self {
246 self.stage(ProgressStage::new(id, name))
247 }
248
249 /// Configures the elapsed duration.
250 ///
251 /// # Parameters
252 ///
253 /// * `elapsed` - Monotonic elapsed duration to carry in the event.
254 ///
255 /// # Returns
256 ///
257 /// This builder with `elapsed` recorded.
258 #[inline]
259 pub const fn elapsed(mut self, elapsed: Duration) -> Self {
260 self.elapsed = elapsed;
261 self
262 }
263
264 /// Builds the progress event.
265 ///
266 /// # Returns
267 ///
268 /// An immutable [`ProgressEvent`] with the configured values.
269 #[inline]
270 pub fn build(self) -> ProgressEvent {
271 ProgressEvent::new(self)
272 }
273}
274
275impl Default for ProgressEventBuilder {
276 /// Creates a builder with default running progress state.
277 ///
278 /// # Returns
279 ///
280 /// A builder equivalent to [`Self::new`].
281 #[inline]
282 fn default() -> Self {
283 Self::new()
284 }
285}