#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ProgressCounters {
total_count: Option<usize>,
completed_count: usize,
active_count: usize,
succeeded_count: usize,
failed_count: usize,
}
impl ProgressCounters {
#[inline]
pub const fn new(total_count: Option<usize>) -> Self {
Self {
total_count,
completed_count: 0,
active_count: 0,
succeeded_count: 0,
failed_count: 0,
}
}
#[inline]
pub const fn with_total_count(mut self, total_count: Option<usize>) -> Self {
self.total_count = total_count;
self
}
#[inline]
pub const fn with_completed_count(mut self, completed_count: usize) -> Self {
self.completed_count = completed_count;
self
}
#[inline]
pub const fn with_active_count(mut self, active_count: usize) -> Self {
self.active_count = active_count;
self
}
#[inline]
pub const fn with_succeeded_count(mut self, succeeded_count: usize) -> Self {
self.succeeded_count = succeeded_count;
self
}
#[inline]
pub const fn with_failed_count(mut self, failed_count: usize) -> Self {
self.failed_count = failed_count;
self
}
#[inline]
pub const fn total_count(&self) -> Option<usize> {
self.total_count
}
#[inline]
pub const fn completed_count(&self) -> usize {
self.completed_count
}
#[inline]
pub const fn active_count(&self) -> usize {
self.active_count
}
#[inline]
pub const fn succeeded_count(&self) -> usize {
self.succeeded_count
}
#[inline]
pub const fn failed_count(&self) -> usize {
self.failed_count
}
#[inline]
pub const fn remaining_count(&self) -> Option<usize> {
match self.total_count {
Some(total_count) => Some(
total_count
.saturating_sub(self.completed_count)
.saturating_sub(self.active_count),
),
None => None,
}
}
#[inline]
pub fn progress_fraction(&self) -> Option<f64> {
self.total_count.map(|total_count| {
if total_count == 0 {
1.0
} else {
(self.completed_count as f64 / total_count as f64).clamp(0.0, 1.0)
}
})
}
#[inline]
pub fn progress_percent(&self) -> Option<f64> {
self.progress_fraction().map(|fraction| fraction * 100.0)
}
}