diff --git a/crates/fj-core/src/layers/validation.rs b/crates/fj-core/src/layers/validation.rs index c43fca8a5..69240632c 100644 --- a/crates/fj-core/src/layers/validation.rs +++ b/crates/fj-core/src/layers/validation.rs @@ -8,15 +8,9 @@ use crate::{ use super::{objects::InsertObject, Command, Event, Layer}; impl Layer { - /// Consume the validation layer, returning any validation errors - pub fn into_result(self) -> Result<(), ValidationErrors> { - let errors = self.into_state().into_errors(); - - if errors.0.is_empty() { - Ok(()) - } else { - Err(errors) - } + /// Take all errors stored in the validation layer + pub fn take_errors(&mut self) -> Result<(), ValidationErrors> { + self.process(TakeErrors, &mut Vec::new()) } } @@ -39,6 +33,38 @@ impl Command for InsertObject { } } +/// Take all errors stored in the validation layer +/// +/// Serves both as a command for and event produced by `Layer`. +pub struct TakeErrors; + +impl Command for TakeErrors { + type Result = Result<(), ValidationErrors>; + type Event = Self; + + fn decide( + self, + state: &Validation, + events: &mut Vec, + ) -> Self::Result { + let errors = ValidationErrors(state.errors.values().cloned().collect()); + + events.push(self); + + if errors.0.is_empty() { + Ok(()) + } else { + Err(errors) + } + } +} + +impl Event for TakeErrors { + fn evolve(&self, state: &mut Validation) { + state.errors.clear(); + } +} + /// Validation of an object failed /// /// Event produced by `Layer`. diff --git a/crates/fj-core/src/validate/mod.rs b/crates/fj-core/src/validate/mod.rs index 178bf79d2..570656a07 100644 --- a/crates/fj-core/src/validate/mod.rs +++ b/crates/fj-core/src/validate/mod.rs @@ -119,11 +119,6 @@ impl Validation { let errors = HashMap::new(); Self { errors, config } } - - /// Drop this instance, returning the errors it contained - pub fn into_errors(mut self) -> ValidationErrors { - ValidationErrors(self.errors.drain().map(|(_, error)| error).collect()) - } } impl Drop for Validation { diff --git a/crates/fj-core/src/validate/solid.rs b/crates/fj-core/src/validate/solid.rs index 05366f644..cc705419d 100644 --- a/crates/fj-core/src/validate/solid.rs +++ b/crates/fj-core/src/validate/solid.rs @@ -236,7 +236,7 @@ mod tests { valid_solid.validate_and_return_first_error()?; // Ignore remaining validation errors. - let _ = core.layers.validation.into_result(); + let _ = core.layers.validation.take_errors(); Ok(()) } @@ -289,7 +289,7 @@ mod tests { valid_solid.validate_and_return_first_error()?; // Ignore remaining validation errors. - let _ = core.layers.validation.into_result(); + let _ = core.layers.validation.take_errors(); Ok(()) } @@ -339,7 +339,7 @@ mod tests { valid_solid.validate_and_return_first_error()?; // Ignore remaining validation errors. - let _ = core.layers.validation.into_result(); + let _ = core.layers.validation.take_errors(); Ok(()) } @@ -379,7 +379,7 @@ mod tests { valid_solid.validate_and_return_first_error()?; // Ignore remaining validation errors. - let _ = core.layers.validation.into_result(); + let _ = core.layers.validation.take_errors(); Ok(()) } diff --git a/crates/fj/src/handle_model.rs b/crates/fj/src/handle_model.rs index 280c2abf0..64a9a00b2 100644 --- a/crates/fj/src/handle_model.rs +++ b/crates/fj/src/handle_model.rs @@ -23,7 +23,7 @@ use crate::Args; /// /// This function is used by Fornjot's own testing infrastructure, but is useful /// beyond that, when using Fornjot directly to define a model. -pub fn handle_model(model: &M, core: Instance) -> Result +pub fn handle_model(model: &M, mut core: Instance) -> Result where for<'r> (&'r M, Tolerance): Triangulate, M: BoundingVolume<3>, @@ -36,7 +36,7 @@ where let args = Args::parse(); if !args.ignore_validation { - core.layers.validation.into_result()?; + core.layers.validation.take_errors()?; } let aabb = model.aabb().unwrap_or(Aabb {