1use crate::{
2 decision::{Decision, Effect},
3 error::Result,
4 policy::Policy,
5 request::Request,
6};
7
8#[derive(Debug)]
9pub struct PolicyEngine {
10 policies: Vec<Policy>,
11 default_effect: Effect,
12}
13
14impl PolicyEngine {
15 pub fn new() -> Self {
17 Self {
18 policies: Vec::new(),
19 default_effect: Effect::Deny,
20 }
21 }
22
23 pub fn from_policies<I>(policies: I) -> Self
25 where
26 I: IntoIterator<Item = Policy>,
27 {
28 let mut engine = Self::new();
29 engine.policies.extend(policies);
30 engine
31 }
32
33 pub fn with_default_effect(mut self, effect: Effect) -> Self {
35 self.default_effect = effect;
36 self
37 }
38
39 pub fn add_policy(&mut self, policy: Policy) {
41 self.policies.push(policy);
42 }
43
44 pub fn evaluate(&self, request: &Request) -> Result<Decision> {
46 for policy in &self.policies {
47 if let Some(effect) = policy.evaluate(request)? {
48 return Ok(Decision::from_effect(effect));
49 }
50 }
51
52 Ok(Decision::from_effect(self.default_effect))
53 }
54}
55
56impl Default for PolicyEngine {
57 fn default() -> Self {
58 Self::new()
59 }
60}