use std::sync::{Arc, Mutex};
use crate::{NestedBars, NestedMeta, ProgressBar, ProgressBarState};
pub struct ProgressBarWeightedNester {
pub(crate) bar: ProgressBar,
pub(crate) taken_fraction: f64,
}
impl ProgressBarWeightedNester {
pub fn take(&mut self, fraction_of_total: f64) -> ProgressBar {
assert!(fraction_of_total.is_finite());
assert!(
fraction_of_total >= 0.0,
"fraction_of_total must be non-negative"
);
assert!(
fraction_of_total <= 1.0,
"fraction_of_total must be at most 1.0"
);
let s = Arc::new(Mutex::new(ProgressBarState::default()));
if let Some(NestedBars {
bars,
meta: NestedMeta::Weighted(weights),
}) = &mut self.bar.state.as_ref().unwrap().lock().unwrap().nested
{
bars.push(s.clone());
weights.push(fraction_of_total);
} else {
unreachable!();
}
self.taken_fraction += fraction_of_total;
ProgressBar { state: Some(s) }
}
pub fn remaining(&mut self) -> ProgressBar {
if self.taken_fraction > 1.01 {
panic!(
"There is no remaning part of the progress bar. You have already used {}% of it",
self.taken_fraction * 100.0
);
}
self.take((1.0 - self.taken_fraction).max(0.0))
}
}
pub struct ProgressBarSizedNester {
pub(crate) bar: ProgressBar,
pub(crate) taken_count: usize,
}
impl ProgressBarSizedNester {
pub fn take(&mut self, count: usize) -> ProgressBar {
let s = Arc::new(Mutex::new(ProgressBarState {
length: Some(count),
..Default::default()
}));
if let Some(NestedBars {
bars,
meta: NestedMeta::Sized(counts),
}) = &mut self.bar.state.as_ref().unwrap().lock().unwrap().nested
{
bars.push(s.clone());
counts.push(count as f64);
} else {
unreachable!();
}
self.taken_count += count;
ProgressBar { state: Some(s) }
}
pub fn remaining(&mut self) -> ProgressBar {
let len = self.bar.state.as_ref().unwrap().lock().unwrap().length;
match len {
Some(len) => {
if let Some(remaining) = len.checked_sub(self.taken_count) {
self.take(remaining)
} else {
panic!(
"There is no remaning part of the progress bar. The bar has a length of {} and you have already used {} for other nested bars.",
len,
self.taken_count
);
}
}
None => {
panic!(
"You cannot call remaining because the original bar didn't have a length set"
);
}
}
}
}
pub struct ProgressBarSummedNester {
pub(crate) bar: ProgressBar,
}
impl ProgressBarSummedNester {
pub fn take(&self) -> ProgressBar {
let s = Arc::new(Mutex::new(ProgressBarState::default()));
if let Some(NestedBars {
bars,
meta: NestedMeta::Summed,
}) = &mut self.bar.state.as_ref().unwrap().lock().unwrap().nested
{
bars.push(s.clone());
} else {
unreachable!();
}
ProgressBar { state: Some(s) }
}
}