use crate::annotations::Annotations;
use crate::document::CadIr;
use crate::report::{Check, LossNote, ValidationReport};
macro_rules! with_draft_core {
($($extra:expr),* $(,)?) => {
&[
Check::Identity,
Check::ReferentialIntegrity,
Check::NativeLinks,
Check::LoopClosure,
Check::CoedgePairing,
Check::ShellTopology,
Check::WireTopology,
Check::CarrierReachability,
Check::ParameterDomain,
Check::Bounds,
Check::GeometricConsistency,
$($extra),*
]
};
}
pub const DRAFT_CORE_CHECKS: &[Check] = with_draft_core!();
pub const RHINO_DRAFT_CHECKS: &[Check] = with_draft_core!(Check::Annotations);
pub const RHINO_INSTANCE_CHECKS: &[Check] = DRAFT_CORE_CHECKS;
pub const CATIA_ADMISSION_CHECKS: &[Check] = DRAFT_CORE_CHECKS;
pub const SLDPRT_EXPORT_PRECONDITION_CHECKS: &[Check] = DRAFT_CORE_CHECKS;
pub fn filter_checks(mut report: ValidationReport, allowed: &[Check]) -> ValidationReport {
report
.findings
.retain(|finding| allowed.contains(&finding.check));
report
}
pub fn admit(ir: &CadIr, allowed: &[Check], losses: Vec<LossNote>) -> ValidationReport {
filter_checks(super::validate_neutral(ir, losses), allowed)
}
pub fn admit_with_annotations(
ir: &CadIr,
annotations: &Annotations,
allowed: &[Check],
losses: Vec<LossNote>,
) -> ValidationReport {
filter_checks(
super::validate_neutral_with_annotations(ir, annotations, losses),
allowed,
)
}
pub fn admit_with_additional_native_identities<'a>(
ir: &'a CadIr,
additional: impl IntoIterator<Item = &'a str>,
allowed: &[Check],
losses: Vec<LossNote>,
) -> ValidationReport {
filter_checks(
super::validate_neutral_with_additional_native_identities(ir, additional, losses),
allowed,
)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::validate::admissibility_freeze::{
accepted_empty, rejected_missing_point, rejected_missing_region,
};
#[test]
fn draft_core_agrees_with_full_on_freeze_fixtures() {
let accepted = accepted_empty();
assert!(super::super::validate_neutral(&accepted, Vec::new()).is_ok());
assert!(admit(&accepted, DRAFT_CORE_CHECKS, Vec::new()).is_ok());
let missing_point = rejected_missing_point("test:model");
assert!(!super::super::validate_neutral(&missing_point, Vec::new()).is_ok());
assert!(!admit(&missing_point, DRAFT_CORE_CHECKS, Vec::new()).is_ok());
let missing_region = rejected_missing_region("test:model");
assert!(!super::super::validate_neutral(&missing_region, Vec::new()).is_ok());
assert!(!admit(&missing_region, DRAFT_CORE_CHECKS, Vec::new()).is_ok());
}
#[test]
fn filter_checks_drops_out_of_set_findings() {
let ir = rejected_missing_point("test:model");
let filtered = admit(&ir, &[Check::Identity], Vec::new());
assert!(
filtered.is_ok(),
"referential_integrity must not reject under Identity-only set: {filtered:?}"
);
}
#[test]
fn documented_route_constants_match_admit_subsets() {
assert_eq!(
DRAFT_CORE_CHECKS,
&[
Check::Identity,
Check::ReferentialIntegrity,
Check::NativeLinks,
Check::LoopClosure,
Check::CoedgePairing,
Check::ShellTopology,
Check::WireTopology,
Check::CarrierReachability,
Check::ParameterDomain,
Check::Bounds,
Check::GeometricConsistency,
]
);
assert_eq!(RHINO_INSTANCE_CHECKS, DRAFT_CORE_CHECKS);
assert_eq!(CATIA_ADMISSION_CHECKS, DRAFT_CORE_CHECKS);
assert_eq!(SLDPRT_EXPORT_PRECONDITION_CHECKS, DRAFT_CORE_CHECKS);
assert_eq!(
RHINO_DRAFT_CHECKS.len(),
DRAFT_CORE_CHECKS.len() + 1,
"Rhino draft is core plus Annotations"
);
assert_eq!(
&RHINO_DRAFT_CHECKS[..DRAFT_CORE_CHECKS.len()],
DRAFT_CORE_CHECKS
);
assert_eq!(
RHINO_DRAFT_CHECKS[DRAFT_CORE_CHECKS.len()],
Check::Annotations
);
assert!(!DRAFT_CORE_CHECKS.contains(&Check::ArenaOrder));
assert!(!DRAFT_CORE_CHECKS.contains(&Check::Counts));
assert!(!RHINO_DRAFT_CHECKS.contains(&Check::ArenaOrder));
let accepted = accepted_empty();
let rejected = rejected_missing_point("test:model");
for allowed in [
DRAFT_CORE_CHECKS,
RHINO_DRAFT_CHECKS,
RHINO_INSTANCE_CHECKS,
CATIA_ADMISSION_CHECKS,
SLDPRT_EXPORT_PRECONDITION_CHECKS,
] {
assert!(admit(&accepted, allowed, Vec::new()).is_ok());
assert!(!admit(&rejected, allowed, Vec::new()).is_ok());
}
}
}