Files
solvecraft/crates/kernel/src/validity.rs
T
Brennen Herbruck ed5bed8f00 Wave 67/509: kernel-cases: sweeps skipped sources (72) (and 3 more)
4 commits, squashed; the originals stay reachable from tag archive/merge-main-develop.

- 75aa8acb6 Brennen Herbruck: kernel-cases: sweeps skipped sources (72)
- 678a70da2 bherbruck: kernel-cases: shells as a graded count, no SMLib verdict where it can't take the record, $OUT
- c24b066d2 bherbruck: kernel-cases: an outcome for geometry with no single manifold answer
- 8764a76ff Brennen Herbruck: kernel-cases: threads cases from #1995 and #3368 (finely faceted booleans), skipped #987 #3130 #3824

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DtL5M41G8Nua7HvuFPZkmJ
2026-10-21 06:52:51 -04:00

75 lines
2.6 KiB
Rust

//! Is a body one valid solid? The kernel regression rig (`tests/kernel-cases`) asks this of every
//! result: the schema 4 record's structure and geometry (`Brep::validate`, `check_geometry`),
//! and, with the `smlib` feature, SMLib's own check of the same record.
use crate::{Body, brep_record};
/// What the validity checks found for one body. `Err` holds why a check failed.
#[derive(Clone, Debug)]
pub struct Validity {
/// The record: structure, then geometry against topology within tolerances.
pub record: Result<(), String>,
/// SMLib's `check(All)` of the record; `None` in a build without SMLib.
pub smlib: Option<SmlibCheck>,
}
/// SMLib's verdict on a body.
#[derive(Clone, Debug)]
pub enum SmlibCheck {
Valid,
Invalid(String),
/// The record can't be built in SMLib yet (a geometry kind the conversion doesn't take): no
/// verdict, and no fault of the body's.
NotSupported(String),
}
impl Validity {
pub fn ok(&self) -> bool {
self.record.is_ok() && !matches!(self.smlib, Some(SmlibCheck::Invalid(_)))
}
}
/// Runs every validity check this build has on `body`.
pub fn validity(body: &Body) -> Validity {
let record = brep_record(body).map_err(|e| e.to_string());
let checked = record.as_ref().map_err(Clone::clone).and_then(|r| {
r.validate().map_err(|e| format!("structure: {e}"))?;
r.check_geometry().map_err(|e| format!("geometry: {e}"))
});
Validity { record: checked, smlib: smlib_validity(body) }
}
#[cfg(feature = "smlib")]
fn smlib_validity(body: &Body) -> Option<SmlibCheck> {
let b = match crate::smlib_body(body) {
Ok(b) => b,
Err(e) => {
let e = e.to_string();
return Some(if e.contains("not supported yet") { SmlibCheck::NotSupported(e) } else { SmlibCheck::Invalid(e) });
}
};
Some(match b.check(solidcraft_smlib::CheckLevel::All) {
Ok(r) if r.is_valid() => SmlibCheck::Valid,
Ok(r) => SmlibCheck::Invalid(format!("SMLib check: {r}")),
Err(e) => SmlibCheck::Invalid(format!("SMLib check: {e}")),
})
}
#[cfg(not(feature = "smlib"))]
fn smlib_validity(_: &Body) -> Option<SmlibCheck> {
None
}
/// Whether this build links SMLib (the `smlib` feature).
pub fn smlib_built() -> bool {
cfg!(feature = "smlib")
}
/// The kernel booleans run on in this process: `"default"` or `"smlib"`. The regression rig
/// refuses to grade a kernel the process isn't running. The SMLib boolean switch
/// (`SOLIDCRAFT_BOOLEANS=smlib`) answers here once it lands; until then this is always
/// `"default"`.
pub fn boolean_kernel() -> &'static str {
"default"
}