1use thiserror::Error;
2
3use crate::{PolicyDefinition, Statement};
4
5pub trait PolicyValidator {
7 type Error;
9
10 fn validate(&self, definition: &PolicyDefinition) -> Result<(), Self::Error>;
15}
16
17#[derive(Debug)]
19pub struct DefaultValidator;
20
21impl PolicyValidator for DefaultValidator {
22 type Error = ValidatorError;
23
24 fn validate(&self, definition: &PolicyDefinition) -> Result<(), Self::Error> {
25 let errors = definition
26 .statements()
27 .iter()
28 .flat_map(|statement| visit_statement(statement))
29 .collect::<Vec<_>>();
30
31 if !errors.is_empty() {
32 return Err(ValidatorError::ValidationSummary(errors));
33 }
34 Ok(())
35 }
36}
37
38fn visit_statement(statement: &Statement) -> Vec<String> {
39 let mut result = vec![];
40 if statement.identities().is_empty() {
41 result.push("Identities list must not be empty".into());
42 }
43 if statement.operations().is_empty() {
44 result.push("Operations list must not be empty".into());
45 }
46 result
47}
48
49#[derive(Debug, Error)]
50pub enum ValidatorError {
51 #[error("An error occurred validating policy definition: {0:?}.")]
52 ValidationSummary(Vec<String>),
53}