greentic_bundle/access/
eval.rs1use super::{GmapPath, GmapRule, Policy};
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct MatchDecision {
5 pub policy: Policy,
6 pub rank: u8,
7}
8
9pub fn eval_policy(rules: &[GmapRule], target: &GmapPath) -> Option<MatchDecision> {
10 let mut best: Option<MatchDecision> = None;
11 let mut best_index = 0usize;
12 for (idx, rule) in rules.iter().enumerate() {
13 if !matches_target(&rule.path, target) {
14 continue;
15 }
16 let rank = specificity_rank(&rule.path);
17 let candidate = MatchDecision {
18 policy: rule.policy.clone(),
19 rank,
20 };
21 match best {
22 None => {
23 best = Some(candidate);
24 best_index = idx;
25 }
26 Some(ref current) => {
27 if rank > current.rank || (rank == current.rank && idx > best_index) {
28 best = Some(candidate);
29 best_index = idx;
30 }
31 }
32 }
33 }
34 best
35}
36
37pub fn eval_with_overlay(
38 tenant_rules: &[GmapRule],
39 team_rules: &[GmapRule],
40 target: &GmapPath,
41) -> Option<MatchDecision> {
42 eval_policy(team_rules, target).or_else(|| eval_policy(tenant_rules, target))
43}
44
45fn matches_target(rule: &GmapPath, target: &GmapPath) -> bool {
46 match (&rule.pack, &rule.flow, &rule.node) {
47 (None, None, None) => true,
48 (Some(pack), None, None) => target.pack.as_deref() == Some(pack.as_str()),
49 (Some(pack), Some(flow), None) => {
50 if flow == "_" {
51 target.pack.as_deref() == Some(pack.as_str())
52 } else {
53 target.pack.as_deref() == Some(pack.as_str())
54 && target.flow.as_deref() == Some(flow.as_str())
55 }
56 }
57 (Some(pack), Some(flow), Some(node)) => {
58 target.pack.as_deref() == Some(pack.as_str())
59 && target.flow.as_deref() == Some(flow.as_str())
60 && target.node.as_deref() == Some(node.as_str())
61 }
62 _ => false,
63 }
64}
65
66fn specificity_rank(path: &GmapPath) -> u8 {
67 match (&path.pack, &path.flow, &path.node) {
68 (None, None, None) => 0,
69 (Some(_), None, None) => 3,
70 (Some(_), Some(flow), None) if flow == "_" => 2,
71 (Some(_), Some(_), None) => 4,
72 (Some(_), Some(_), Some(_)) => 5,
73 _ => 0,
74 }
75}