Skip to content

Commit

Permalink
Merge pull request hannobraun#2242 from hannobraun/validation
Browse files Browse the repository at this point in the history
Implement `ValidationCheck` for the check
  • Loading branch information
hannobraun authored Feb 28, 2024
2 parents fb77fed + 37688be commit 49306ad
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
9 changes: 7 additions & 2 deletions crates/fj-core/src/validate/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
objects::Cycle,
validation::{ValidationCheck, ValidationConfig, ValidationError},
validation::{
checks::AdjacentHalfEdgesNotConnected, ValidationCheck,
ValidationConfig, ValidationError,
},
};

use super::Validate;
Expand All @@ -11,6 +14,8 @@ impl Validate for Cycle {
config: &ValidationConfig,
errors: &mut Vec<ValidationError>,
) {
errors.extend(self.check(config).map(Into::into));
errors.extend(
AdjacentHalfEdgesNotConnected::check(self, config).map(Into::into),
);
}
}
14 changes: 8 additions & 6 deletions crates/fj-core/src/validation/checks/half_edge_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ pub struct AdjacentHalfEdgesNotConnected {
pub unconnected_half_edges: [Handle<HalfEdge>; 2],
}

impl ValidationCheck<AdjacentHalfEdgesNotConnected> for Cycle {
impl ValidationCheck<Cycle> for AdjacentHalfEdgesNotConnected {
fn check(
&self,
object: &Cycle,
config: &ValidationConfig,
) -> impl Iterator<Item = AdjacentHalfEdgesNotConnected> {
self.half_edges().pairs().filter_map(|(first, second)| {
) -> impl Iterator<Item = Self> {
object.half_edges().pairs().filter_map(|(first, second)| {
let end_pos_of_first_half_edge = {
let [_, end] = first.boundary().inner;
first.path().point_from_path_coords(end)
Expand Down Expand Up @@ -80,12 +80,14 @@ mod tests {
Core,
};

use super::AdjacentHalfEdgesNotConnected;

#[test]
fn adjacent_half_edges_connected() -> anyhow::Result<()> {
let mut core = Core::new();

let valid = Cycle::polygon([[0., 0.], [1., 0.], [1., 1.]], &mut core);
valid.check_and_return_first_error()?;
AdjacentHalfEdgesNotConnected::check_and_return_first_error(&valid)?;

let invalid = valid.update_half_edge(
valid.half_edges().first(),
Expand All @@ -94,7 +96,7 @@ mod tests {
},
&mut core,
);
invalid.check_and_expect_one_error();
AdjacentHalfEdgesNotConnected::check_and_expect_one_error(&invalid);

Ok(())
}
Expand Down
25 changes: 15 additions & 10 deletions crates/fj-core/src/validation/validation_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ use super::ValidationConfig;
///
/// This trait is implemented once per validation check and object it applies
/// to. `Self` is the object, while `T` identifies the validation check.
pub trait ValidationCheck<T> {
pub trait ValidationCheck<T>: Sized {
/// Run the validation check on the implementing object
fn check(&self, config: &ValidationConfig) -> impl Iterator<Item = T>;
fn check(
object: &T,
config: &ValidationConfig,
) -> impl Iterator<Item = Self>;

/// Convenience method to run the check return the first error
///
/// This method is designed for convenience over flexibility (it is intended
/// for use in unit tests), and thus always uses the default configuration.
fn check_and_return_first_error(&self) -> Result<(), T> {
let errors =
self.check(&ValidationConfig::default()).collect::<Vec<_>>();
fn check_and_return_first_error(object: &T) -> Result<(), Self> {
let config = ValidationConfig::default();
let mut errors = Self::check(object, &config);

if let Some(err) = errors.into_iter().next() {
if let Some(err) = errors.next() {
return Err(err);
}

Expand All @@ -29,14 +32,14 @@ pub trait ValidationCheck<T> {
///
/// This method is designed for convenience over flexibility (it is intended
/// for use in unit tests), and thus always uses the default configuration.
fn check_and_expect_one_error(&self)
fn check_and_expect_one_error(object: &T) -> Self
where
T: Display,
Self: Display,
{
let config = ValidationConfig::default();
let mut errors = self.check(&config).peekable();
let mut errors = Self::check(object, &config).peekable();

errors
let err = errors
.next()
.expect("Expected one validation error; none found");

Expand All @@ -49,5 +52,7 @@ pub trait ValidationCheck<T> {

panic!("Expected only one validation error")
}

err
}
}

0 comments on commit 49306ad

Please sign in to comment.