use crate::diagnostics::ValidationReport;
use crate::model::{AnalysisContext, PipelineContract};
use super::{
com, control_flow, data_flow, document, execution, extensions, failure, governance, graph,
lineage, quality, references, scheduling, security, structural,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ValidationPhase {
Document,
Com,
Structural,
Graph,
References,
DataFlow,
ControlFlow,
Execution,
Scheduling,
Quality,
Failure,
Lineage,
Security,
Governance,
Extensions,
}
impl ValidationPhase {
pub const ALL: [Self; 15] = [
Self::Document,
Self::Com,
Self::Structural,
Self::Graph,
Self::References,
Self::DataFlow,
Self::ControlFlow,
Self::Execution,
Self::Scheduling,
Self::Quality,
Self::Failure,
Self::Lineage,
Self::Security,
Self::Governance,
Self::Extensions,
];
}
pub fn validate(contract: &PipelineContract) -> ValidationReport {
let ctx = AnalysisContext::build(contract);
validate_with_context(&ctx)
}
pub fn validate_with_context(ctx: &AnalysisContext<'_>) -> ValidationReport {
#[cfg(feature = "parallel")]
{
validate_parallel(ctx)
}
#[cfg(not(feature = "parallel"))]
{
validate_sequential_with_context(ctx)
}
}
pub fn validate_sequential(contract: &PipelineContract) -> ValidationReport {
let ctx = AnalysisContext::build(contract);
validate_sequential_with_context(&ctx)
}
pub fn validate_sequential_with_context(ctx: &AnalysisContext<'_>) -> ValidationReport {
let mut report = ValidationReport::new();
for phase in ValidationPhase::ALL {
report.extend(run_phase(phase, ctx));
}
report.sort_deterministic();
report
}
#[cfg(feature = "parallel")]
fn validate_parallel(ctx: &AnalysisContext<'_>) -> ValidationReport {
use rayon::prelude::*;
let mut reports: Vec<ValidationReport> = ValidationPhase::ALL
.into_par_iter()
.map(|phase| run_phase(phase, ctx))
.collect();
let mut report = ValidationReport::new();
for phase_report in reports.drain(..) {
report.extend(phase_report);
}
report.sort_deterministic();
report
}
pub(crate) fn run_phase(phase: ValidationPhase, ctx: &AnalysisContext<'_>) -> ValidationReport {
let contract = ctx.contract;
match phase {
ValidationPhase::Document => document::validate(contract),
ValidationPhase::Com => com::validate(contract),
ValidationPhase::Structural => structural::validate(contract),
ValidationPhase::Graph => graph::validate_with_context(ctx),
ValidationPhase::References => references::validate_with_context(ctx),
ValidationPhase::DataFlow => data_flow::validate_with_context(ctx),
ValidationPhase::ControlFlow => control_flow::validate_with_context(ctx),
ValidationPhase::Execution => execution::validate(contract),
ValidationPhase::Scheduling => scheduling::validate(contract),
ValidationPhase::Quality => quality::validate_with_context(ctx),
ValidationPhase::Failure => failure::validate_with_context(ctx),
ValidationPhase::Lineage => lineage::validate_with_context(ctx),
ValidationPhase::Security => security::validate(contract),
ValidationPhase::Governance => governance::validate(contract),
ValidationPhase::Extensions => extensions::validate(contract),
}
}