fj_kernel/services/
validation.rs

1use 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/// Errors that occurred while validating the objects inserted into the stores
12#[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
82/// The command accepted by the validation service
83pub enum ValidationCommand {
84    /// Validate the provided object
85    ValidateObject {
86        /// The object to validate
87        object: Object<BehindHandle>,
88    },
89
90    /// Validate the provided objects, discard all other validation errors
91    OnlyValidate {
92        /// The objects to validate
93        objects: ObjectSet,
94    },
95}
96
97/// The event produced by the validation service
98#[derive(Clone)]
99pub enum ValidationEvent {
100    /// Validation of an object failed
101    ValidationFailed {
102        /// The object for which validation failed
103        object: Object<BehindHandle>,
104
105        /// The validation error
106        err: ValidationError,
107    },
108
109    /// All stored validation errors are being cleared
110    ClearErrors,
111}