1use crate::store::AttackStore;
2use crate::domain::AttackObject;
3
4#[derive(Debug, PartialEq, Eq)]
5pub enum ValidationResult {
6 Valid,
7 Deprecated { replaced_by: Option<String> },
8 Revoked { replaced_by: Option<String> },
9 Unknown,
10}
11
12pub struct Validator<'a> {
13 store: &'a AttackStore,
14}
15
16impl<'a> Validator<'a> {
17 pub fn new(store: &'a AttackStore) -> Self {
18 Self { store }
19 }
20
21 pub fn validate_id(&self, id: &str) -> ValidationResult {
22 if let Some(obj) = self.get_any_object(id) {
23 if obj.revoked() {
24 ValidationResult::Revoked { replaced_by: self.get_replacement(id) }
25 } else if obj.deprecated() {
26 ValidationResult::Deprecated { replaced_by: self.get_replacement(id) }
27 } else {
28 ValidationResult::Valid
29 }
30 } else {
31 ValidationResult::Unknown
32 }
33 }
34
35 fn get_any_object(&self, id: &str) -> Option<&dyn AttackObject> {
36 if let Some(o) = self.store.get_tactic(id) { return Some(o); }
37 if let Some(o) = self.store.get_technique(id) { return Some(o); }
38 if let Some(o) = self.store.get_group(id) { return Some(o); }
39 if let Some(o) = self.store.get_software(id) { return Some(o); }
40 if let Some(o) = self.store.get_mitigation(id) { return Some(o); }
41 if let Some(o) = self.store.get_data_source(id) { return Some(o); }
42 if let Some(o) = self.store.get_data_component(id) { return Some(o); }
43 if let Some(o) = self.store.get_campaign(id) { return Some(o); }
44 if let Some(o) = self.store.get_matrix(id) { return Some(o); }
45 if let Some(o) = self.store.get_analytic(id) { return Some(o); }
46 if let Some(o) = self.store.get_detection_strategy(id) { return Some(o); }
47 None
48 }
49
50 fn get_replacement(&self, id: &str) -> Option<String> {
51 self.store.get_replacement(id).map(|s| s.to_string())
52 }
53}