use crate::pipeline::reporter::Reporter;
use crate::spec::types::ParityFailure;
#[cfg(loom)]
use loom::sync::Mutex;
#[cfg(not(loom))]
use std::sync::Mutex;
#[inline]
pub(crate) fn start(reporters: &[Mutex<Option<Box<dyn Reporter>>>], op_id: &str, count: usize) {
for reporter in reporters {
with_reporter(reporter, |reporter| reporter.on_op_start(op_id, count));
}
}
#[inline]
pub(crate) fn pass(reporters: &[Mutex<Option<Box<dyn Reporter>>>], op_id: &str, label: &str) {
for reporter in reporters {
with_reporter(reporter, |reporter| reporter.on_pass(op_id, label));
}
}
#[inline]
pub(crate) fn fail(reporters: &[Mutex<Option<Box<dyn Reporter>>>], failure: &ParityFailure) {
for reporter in reporters {
with_reporter(reporter, |reporter| reporter.on_fail(failure));
}
}
#[inline]
pub(crate) fn done(
reporters: &[Mutex<Option<Box<dyn Reporter>>>],
op_id: &str,
pass_count: usize,
fail_count: usize,
) {
for reporter in reporters {
with_reporter(reporter, |reporter| {
reporter.on_op_done(op_id, pass_count, fail_count);
});
}
}
fn with_reporter(slot: &Mutex<Option<Box<dyn Reporter>>>, call: impl FnOnce(&mut dyn Reporter)) {
let Some(mut reporter) = take_reporter(slot) else {
return;
};
call(reporter.as_mut());
if let Ok(mut guard) = slot.lock() {
if guard.is_none() {
*guard = Some(reporter);
}
}
}
fn take_reporter(slot: &Mutex<Option<Box<dyn Reporter>>>) -> Option<Box<dyn Reporter>> {
let Ok(mut guard) = slot.lock() else {
return None;
};
guard.take()
}