use super::types::{FailedTrial, SeatFailure, SeatOutcome, SeatRefusal};
use crate::report::{RunAttempt, RunReport, SelectionOutcome, TrialConclusion, TrialReport};
pub fn seat_verdict(report: &RunReport) -> Result<SeatOutcome, SeatRefusal> {
let denominator = report.denominator();
match report.selection() {
SelectionOutcome::Satisfied => {}
SelectionOutcome::UnsatisfiedByEmptySelection => {
return Err(SeatRefusal::NothingSelected { denominator });
}
SelectionOutcome::EmptyAsStated(reason) => {
return Ok(SeatOutcome::NoWorkAsStated {
reason,
denominator,
});
}
}
let selected: Vec<&TrialReport> = report
.census()
.iter()
.filter_map(|accounting| accounting.disposition().report())
.collect();
let failed: Vec<FailedTrial> = selected.iter().copied().filter_map(failed_trial).collect();
if failed.is_empty() {
Ok(SeatOutcome::EveryTrialConcluded {
selected: selected.len(),
denominator,
})
} else {
Err(SeatRefusal::RunFailed {
failed,
selected: selected.len(),
denominator,
})
}
}
pub fn lens_verdict(report: &TrialReport) -> Result<(), SeatRefusal> {
match failed_trial(report) {
None => Ok(()),
Some(failed) => Err(SeatRefusal::trial_failed(failed)),
}
}
fn failed_trial(report: &TrialReport) -> Option<FailedTrial> {
let failure = match report.attempt() {
RunAttempt::Executed(TrialConclusion::Passed) => return None,
RunAttempt::Executed(TrialConclusion::Refused(finding)) => {
SeatFailure::CheckRefused(finding.clone())
}
RunAttempt::SkippedWithReason(reason) => SeatFailure::NotRun(*reason),
RunAttempt::TimedOut => {
SeatFailure::PastTimeBudget(report.standing().key().invocation().time())
}
RunAttempt::InfrastructureFailed(failure) => SeatFailure::HarnessFailed(failure.clone()),
};
Some(FailedTrial::recorded(
report.trial(),
report.site(),
failure,
))
}