aaai_core/audit/
engine.rs1use crate::config::definition::AuditDefinition;
4use crate::diff::entry::{DiffEntry, DiffType};
5use super::result::{AuditResult, AuditStatus, FileAuditResult};
6use super::strategy;
7
8pub struct AuditEngine;
9
10impl AuditEngine {
11 pub fn evaluate(diffs: &[DiffEntry], definition: &AuditDefinition) -> AuditResult {
13 let mut results = Vec::new();
14
15 for diff in diffs {
16 let result = judge(diff, definition);
17 results.push(result);
18 }
19
20 AuditResult::new(results)
21 }
22}
23
24fn judge(diff: &DiffEntry, definition: &AuditDefinition) -> FileAuditResult {
25 if diff.diff_type.is_error() {
27 return FileAuditResult {
28 diff: diff.clone(),
29 entry: None,
30 status: AuditStatus::Error,
31 detail: diff.error_detail.clone().or_else(|| {
32 Some("File could not be read or compared.".into())
33 }),
34 };
35 }
36
37 if diff.diff_type == DiffType::Unchanged {
39 return FileAuditResult {
40 diff: diff.clone(),
41 entry: definition.find_entry(&diff.path).cloned(),
42 status: AuditStatus::Ok,
43 detail: None,
44 };
45 }
46
47 let entry = match definition.find_entry(&diff.path) {
49 Some(e) => e,
50 None => {
51 return FileAuditResult {
52 diff: diff.clone(),
53 entry: None,
54 status: AuditStatus::Pending,
55 detail: Some("No audit rule defined for this path.".into()),
56 };
57 }
58 };
59
60 if !entry.enabled {
62 return FileAuditResult {
63 diff: diff.clone(),
64 entry: Some(entry.clone()),
65 status: AuditStatus::Ignored,
66 detail: Some("Entry is disabled.".into()),
67 };
68 }
69
70 if entry.diff_type != diff.diff_type {
72 return FileAuditResult {
73 diff: diff.clone(),
74 entry: Some(entry.clone()),
75 status: AuditStatus::Failed,
76 detail: Some(format!(
77 "Expected diff type {:?} but found {:?}.",
78 entry.diff_type, diff.diff_type
79 )),
80 };
81 }
82
83 match strategy::evaluate(&entry.strategy, diff) {
85 Ok(()) => FileAuditResult {
86 diff: diff.clone(),
87 entry: Some(entry.clone()),
88 status: AuditStatus::Ok,
89 detail: None,
90 },
91 Err(msg) => FileAuditResult {
92 diff: diff.clone(),
93 entry: Some(entry.clone()),
94 status: AuditStatus::Failed,
95 detail: Some(msg),
96 },
97 }
98}