use crate::{
geometry::Geometry,
objects::{AnyObject, Stored},
validation::{Validation, ValidationError, ValidationErrors},
};
use super::{Command, Event, Layer};
impl Layer<Validation> {
pub fn take_errors(&mut self) -> Result<(), ValidationErrors> {
self.process(TakeErrors, &mut Vec::new())
}
}
pub struct ValidateObject<'r> {
pub object: AnyObject<Stored>,
pub geometry: &'r Geometry,
}
impl Command<Validation> for ValidateObject<'_> {
type Result = ();
type Event = ValidationFailed;
fn decide(self, state: &Validation, events: &mut Vec<Self::Event>) {
let mut errors = Vec::new();
self.object
.validate(&state.config, &mut errors, self.geometry);
for err in errors {
events.push(ValidationFailed {
object: self.object.clone(),
err,
});
}
}
}
pub struct TakeErrors;
impl Command<Validation> for TakeErrors {
type Result = Result<(), ValidationErrors>;
type Event = Self;
fn decide(
self,
state: &Validation,
events: &mut Vec<Self::Event>,
) -> Self::Result {
let errors = ValidationErrors(state.errors.values().cloned().collect());
events.push(self);
if errors.0.is_empty() {
Ok(())
} else {
Err(errors)
}
}
}
impl Event<Validation> for TakeErrors {
fn evolve(&self, state: &mut Validation) {
state.errors.clear();
}
}
#[derive(Clone)]
pub struct ValidationFailed {
pub object: AnyObject<Stored>,
pub err: ValidationError,
}
impl Event<Validation> for ValidationFailed {
fn evolve(&self, state: &mut Validation) {
state.errors.insert(self.object.id(), self.err.clone());
}
}