Skip to main content

qubit_batch/process/
batch_process_result.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::{
11    fmt,
12    time::Duration,
13};
14
15use crate::BatchProcessResultBuilder;
16
17/// Structured result produced by a batch processor.
18///
19/// The result distinguishes completed input items from successfully processed
20/// items because some processors can report a success count, such as affected
21/// database rows, that differs from the number of input items whose chunk
22/// returned.
23///
24/// ```rust
25/// use std::time::Duration;
26///
27/// use qubit_batch::BatchProcessResultBuilder;
28///
29/// let result = BatchProcessResultBuilder::builder(3)
30///     .completed_count(3)
31///     .processed_count(3)
32///     .chunk_count(1)
33///     .elapsed(Duration::ZERO)
34///     .build()
35///     .expect("process result counters should be consistent");
36///
37/// assert!(result.is_success());
38/// assert_eq!(result.item_count(), 3);
39/// assert_eq!(result.chunk_count(), 1);
40/// ```
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct BatchProcessResult {
43    /// Declared item count for the batch.
44    item_count: usize,
45    /// Number of input items whose processing reached a terminal outcome.
46    completed_count: usize,
47    /// Number of items reported as successfully processed.
48    processed_count: usize,
49    /// Number of chunks submitted by the processor.
50    chunk_count: usize,
51    /// Total monotonic elapsed duration.
52    elapsed: Duration,
53}
54
55impl BatchProcessResult {
56    /// Starts building a batch process result.
57    ///
58    /// # Parameters
59    ///
60    /// * `item_count` - Declared item count for the batch.
61    ///
62    /// # Returns
63    ///
64    /// A result builder initialized with zero counters and zero elapsed time.
65    #[inline]
66    pub const fn builder(item_count: usize) -> BatchProcessResultBuilder {
67        BatchProcessResultBuilder::builder(item_count)
68    }
69
70    /// Creates a new batch process result from a validated builder.
71    ///
72    /// # Parameters
73    ///
74    /// * `builder` - Validated process result builder carrying all result
75    ///   fields.
76    ///
77    /// # Returns
78    ///
79    /// A fully populated batch process result.
80    #[inline]
81    pub(crate) const fn new(builder: BatchProcessResultBuilder) -> Self {
82        Self {
83            item_count: builder.item_count,
84            completed_count: builder.completed_count,
85            processed_count: builder.processed_count,
86            chunk_count: builder.chunk_count,
87            elapsed: builder.elapsed,
88        }
89    }
90
91    /// Returns the declared item count.
92    ///
93    /// # Returns
94    ///
95    /// The expected number of input items.
96    #[inline]
97    pub const fn item_count(&self) -> usize {
98        self.item_count
99    }
100
101    /// Returns how many input items reached a terminal outcome.
102    ///
103    /// # Returns
104    ///
105    /// The number of completed input items.
106    #[inline]
107    pub const fn completed_count(&self) -> usize {
108        self.completed_count
109    }
110
111    /// Returns how many items were reported as successfully processed.
112    ///
113    /// # Returns
114    ///
115    /// The processor-reported success count.
116    #[inline]
117    pub const fn processed_count(&self) -> usize {
118        self.processed_count
119    }
120
121    /// Returns the number of chunks submitted by the processor.
122    ///
123    /// # Returns
124    ///
125    /// The submitted chunk count.
126    #[inline]
127    pub const fn chunk_count(&self) -> usize {
128        self.chunk_count
129    }
130
131    /// Returns the total monotonic elapsed duration.
132    ///
133    /// # Returns
134    ///
135    /// The elapsed duration for this batch processing attempt.
136    #[inline]
137    pub const fn elapsed(&self) -> Duration {
138        self.elapsed
139    }
140
141    /// Returns whether all declared items were processed successfully.
142    ///
143    /// # Returns
144    ///
145    /// `true` when every declared item completed and was reported as processed.
146    #[inline]
147    pub const fn is_success(&self) -> bool {
148        self.completed_count == self.item_count && self.processed_count == self.item_count
149    }
150}
151
152impl fmt::Display for BatchProcessResult {
153    /// Formats a concise summary of this batch process result.
154    ///
155    /// # Parameters
156    ///
157    /// * `f` - Formatter receiving the summary text.
158    ///
159    /// # Returns
160    ///
161    /// The formatter result.
162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163        write!(
164            f,
165            "processed {}/{} items in {} chunks ({:?})",
166            self.processed_count, self.item_count, self.chunk_count, self.elapsed
167        )
168    }
169}