fj_kernel/services/
validation.rs1use std::{collections::BTreeMap, thread};
2
3use crate::{
4 objects::{BehindHandle, Object, ObjectSet},
5 storage::ObjectId,
6 validate::ValidationError,
7};
8
9use super::State;
10
11#[derive(Default)]
13pub struct Validation {
14 errors: BTreeMap<ObjectId, ValidationError>,
15}
16
17impl Drop for Validation {
18 fn drop(&mut self) {
19 let num_errors = self.errors.len();
20 if num_errors > 0 {
21 println!(
22 "Dropping `Validation` with {num_errors} unhandled validation \
23 errors:"
24 );
25
26 for err in self.errors.values() {
27 println!("{}", err);
28 }
29
30 if !thread::panicking() {
31 panic!();
32 }
33 }
34 }
35}
36
37impl State for Validation {
38 type Command = ValidationCommand;
39 type Event = ValidationEvent;
40
41 fn decide(&self, command: Self::Command, events: &mut Vec<Self::Event>) {
42 let mut errors = Vec::new();
43
44 match command {
45 ValidationCommand::ValidateObject { object } => {
46 object.validate(&mut errors);
47
48 for err in errors {
49 events.push(ValidationEvent::ValidationFailed {
50 object: object.clone(),
51 err,
52 });
53 }
54 }
55 ValidationCommand::OnlyValidate { objects } => {
56 events.push(ValidationEvent::ClearErrors);
57
58 for object in objects {
59 object.validate(&mut errors);
60
61 for err in errors.drain(..) {
62 events.push(ValidationEvent::ValidationFailed {
63 object: object.clone(),
64 err,
65 });
66 }
67 }
68 }
69 }
70 }
71
72 fn evolve(&mut self, event: &Self::Event) {
73 match event {
74 ValidationEvent::ValidationFailed { object, err } => {
75 self.errors.insert(object.id(), err.clone());
76 }
77 ValidationEvent::ClearErrors => self.errors.clear(),
78 }
79 }
80}
81
82pub enum ValidationCommand {
84 ValidateObject {
86 object: Object<BehindHandle>,
88 },
89
90 OnlyValidate {
92 objects: ObjectSet,
94 },
95}
96
97#[derive(Clone)]
99pub enum ValidationEvent {
100 ValidationFailed {
102 object: Object<BehindHandle>,
104
105 err: ValidationError,
107 },
108
109 ClearErrors,
111}