use crate::{
Child, Execution, Inert, NoPulse, PhaseSpec, PlanError, Pulse, Report, Stop, StopReason,
};
pub trait ProgressExt: Stop + Report {
#[inline]
#[track_caller]
fn step(&self, completed: u64) -> Result<(), StopReason> {
if is_no_pulse(self) {
return Ok(());
}
self.advance(completed);
self.check()
}
#[inline]
fn live(&self) -> Option<&Self> {
if !is_no_pulse(self) && (self.may_stop() || self.may_report()) {
Some(self)
} else {
None
}
}
fn split_array<const N: usize>(
&self,
execution: Execution,
parts: [PhaseSpec<'_>; N],
) -> Result<[Child<'_>; N], PlanError>
where
Self: Pulse,
{
match self.split(execution, &parts)?.try_into() {
Ok(children) => Ok(children),
Err(children) => wrong_child_count(children.len(), N),
}
}
}
impl<T: Stop + Report + ?Sized> ProgressExt for T {}
#[inline]
fn is_no_pulse<T: ?Sized>(value: &T) -> bool {
core::ptr::addr_eq(value, &NoPulse)
&& core::mem::size_of_val(value) == core::mem::size_of::<Inert>()
}
#[cold]
#[inline(never)]
fn wrong_child_count(found: usize, parts: usize) -> ! {
panic!("Pulse::split returned {found} children for {parts} parts")
}