Skip to content

Commit

Permalink
make reference count error be contained within the object's error type
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-folsom committed Jan 14, 2024
1 parent 8ac40bb commit 20cd5eb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 39 deletions.
5 changes: 0 additions & 5 deletions crates/fj-core/src/validate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ mod solid;
mod surface;
mod vertex;

use self::references::ReferenceCountError;
pub use self::{
cycle::CycleValidationError, edge::EdgeValidationError,
face::FaceValidationError, shell::ShellValidationError,
Expand Down Expand Up @@ -196,10 +195,6 @@ pub enum ValidationError {
/// `Sketch` validation error
#[error("`Sketch` validation error")]
Sketch(#[from] SketchValidationError),

/// Reference validation error
#[error("`Reference` validation error")]
ReferenceCount(#[from] ReferenceCountError),
}

impl From<Infallible> for ValidationError {
Expand Down
28 changes: 11 additions & 17 deletions crates/fj-core/src/validate/references.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;
use std::hash::Hash;

use crate::objects::{Cycle, Face, HalfEdge, Region};
use crate::storage::Handle;

use super::ValidationError;
Expand All @@ -20,33 +19,28 @@ impl<T: Eq + PartialEq + Hash> ReferenceCounter<T> {
.and_modify(|count| *count += 1)
.or_insert(1);
}

pub fn has_multiple(&self) -> bool {
self.0.iter().any(|(_, count)| *count > 1)
}
}

pub trait ValidateReferences {
pub trait ValidateReferences<T> {
fn validate(&self, errors: &mut Vec<ValidationError>);
}

macro_rules! impl_validate {
($($ty:ty, $err:path;)*) => {
/// Find errors and convert to [`ValidationError`]
#[macro_export]
macro_rules! validate_references {
($errors:ident, $error_ty:ty;$($counter:ident, $err:expr;)*) => {
$(
impl ValidateReferences for ReferenceCounter<$ty> {
fn validate(&self, errors: &mut Vec<ValidationError>) {
if self.0.iter().any(|(_, count)| *count > 1) {
errors.push($err.into());
}
}
if $counter.has_multiple() {
$errors.push(Into::<$error_ty>::into($err).into());
}
)*
};
}

impl_validate!(
Region, ReferenceCountError::Region;
Face, ReferenceCountError::Face;
HalfEdge, ReferenceCountError::HalfEdge;
Cycle, ReferenceCountError::Cycle;
);

#[derive(Clone, Debug, thiserror::Error)]
pub enum ReferenceCountError {
/// [`Region`] referenced by more than one [`Face`]
Expand Down
25 changes: 18 additions & 7 deletions crates/fj-core/src/validate/sketch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::objects::Sketch;
use crate::{objects::Sketch, validate_references};

use super::{
references::{ReferenceCounter, ValidateReferences},
references::{ReferenceCountError, ReferenceCounter},
Validate, ValidationConfig, ValidationError,
};

Expand All @@ -24,6 +24,9 @@ pub enum SketchValidationError {
/// [`Cycle`] referenced by more than one [`crate::objects::Region`]
#[error("[`Cycle`] referenced by more than one [`Region`]")]
CycleMultipleReferences,
/// Object within sketch referenced by more than one other object
#[error("Object referenced by more than one other Objects")]
MultipleReferences(#[from] ReferenceCountError),
}

impl SketchValidationError {
Expand All @@ -46,8 +49,11 @@ impl SketchValidationError {
})
});

referenced_cycles.validate(errors);
referenced_edges.validate(errors);
validate_references!(
errors, SketchValidationError;
referenced_edges, ReferenceCountError::HalfEdge;
referenced_cycles, ReferenceCountError::Cycle;
);
}
}

Expand All @@ -59,7 +65,8 @@ mod tests {
operations::{build::BuildHalfEdge, insert::Insert},
services::Services,
validate::{
references::ReferenceCountError, Validate, ValidationError,
references::ReferenceCountError, SketchValidationError, Validate,
ValidationError,
},
};

Expand All @@ -80,7 +87,9 @@ mod tests {
]);
assert_contains_err!(
invalid_sketch,
ValidationError::ReferenceCount(ReferenceCountError::Cycle)
ValidationError::Sketch(SketchValidationError::MultipleReferences(
ReferenceCountError::Cycle
))
);

let valid_sketch = Sketch::new(vec![Region::new(
Expand Down Expand Up @@ -123,7 +132,9 @@ mod tests {
.insert(&mut services)]);
assert_contains_err!(
invalid_sketch,
ValidationError::ReferenceCount(ReferenceCountError::HalfEdge)
ValidationError::Sketch(SketchValidationError::MultipleReferences(
ReferenceCountError::HalfEdge
))
);

let valid_sketch =
Expand Down
37 changes: 27 additions & 10 deletions crates/fj-core/src/validate/solid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use std::iter::repeat;
use crate::{
objects::{Solid, Vertex},
storage::Handle,
validate_references,
};
use fj_math::Point;

use super::{
references::{ReferenceCounter, ValidateReferences},
references::{ReferenceCountError, ReferenceCounter},
Validate, ValidationConfig, ValidationError,
};

Expand Down Expand Up @@ -64,6 +65,10 @@ pub enum SolidValidationError {
/// Position of second vertex
position_b: Point<3>,
},

/// Object within sketch referenced by more than one other object
#[error("Object referenced by more than one other Objects")]
MultipleReferences(#[from] ReferenceCountError),
}

impl SolidValidationError {
Expand Down Expand Up @@ -157,10 +162,13 @@ impl SolidValidationError {
})
});

referenced_faces.validate(errors);
referenced_regions.validate(errors);
referenced_cycles.validate(errors);
referenced_edges.validate(errors);
validate_references!(
errors, SolidValidationError;
referenced_regions, ReferenceCountError::Region;
referenced_faces, ReferenceCountError::Face;
referenced_edges, ReferenceCountError::HalfEdge;
referenced_cycles, ReferenceCountError::Cycle;
);
}
}

Expand All @@ -176,7 +184,8 @@ mod tests {
},
services::Services,
validate::{
references::ReferenceCountError, Validate, ValidationError,
references::ReferenceCountError, SolidValidationError, Validate,
ValidationError,
},
};

Expand Down Expand Up @@ -218,7 +227,9 @@ mod tests {

assert_contains_err!(
invalid_solid,
ValidationError::ReferenceCount(ReferenceCountError::Face)
ValidationError::Solid(SolidValidationError::MultipleReferences(
ReferenceCountError::Face
))
);

let valid_solid = Solid::new(vec![]).insert(&mut services);
Expand Down Expand Up @@ -267,7 +278,9 @@ mod tests {

assert_contains_err!(
invalid_solid,
ValidationError::ReferenceCount(ReferenceCountError::Region)
ValidationError::Solid(SolidValidationError::MultipleReferences(
ReferenceCountError::Region
))
);

let valid_solid = Solid::new(vec![]).insert(&mut services);
Expand Down Expand Up @@ -313,7 +326,9 @@ mod tests {

assert_contains_err!(
invalid_solid,
ValidationError::ReferenceCount(ReferenceCountError::Cycle)
ValidationError::Solid(SolidValidationError::MultipleReferences(
ReferenceCountError::Cycle
))
);

let valid_solid = Solid::new(vec![]).insert(&mut services);
Expand Down Expand Up @@ -352,7 +367,9 @@ mod tests {

assert_contains_err!(
invalid_solid,
ValidationError::ReferenceCount(ReferenceCountError::HalfEdge)
ValidationError::Solid(SolidValidationError::MultipleReferences(
ReferenceCountError::HalfEdge
))
);

let valid_solid = Solid::new(vec![]).insert(&mut services);
Expand Down

0 comments on commit 20cd5eb

Please sign in to comment.