ephemeris_forge_github/plan/
rulesets.rs1use ephemeris_forge::{Caller, Collection, FieldDiff, Report};
2
3use crate::api::model;
4use crate::operation::rulesets::Operation;
5use crate::{Ruleset, Rulesets};
6
7pub(super) fn plan(
8 config: Option<&Rulesets>,
9 live: &[model::Ruleset],
10 caller: Option<&Caller>,
11 report: &mut Report,
12) -> Vec<Operation> {
13 let Some(config) = config else {
14 return Vec::new();
15 };
16 for ruleset in live {
17 report
18 .limitations
19 .extend(ruleset.limitations.iter().cloned());
20 }
21 Collection {
22 noun: "ruleset",
23 mode: config.mode,
24 }
25 .plan(
26 &config.rulesets,
27 live,
28 report,
29 |ruleset, name| ruleset.name == name,
30 |name, desired, actual, _| {
31 let desired = match caller {
32 Some(Caller::App {
33 id,
34 slug: _,
35 admin: _,
36 }) => i64::try_from(*id)
37 .map_or_else(|_| desired.clone(), |id| desired.clone().with_own_app(id)),
38 _ => desired.clone(),
39 };
40 let diff = compare(&desired, actual);
41 let (name, ruleset) = (name.to_owned(), Box::new(desired));
42 let operation = match actual {
43 _ if !diff.has_changes() => None,
44 Some(actual) => Some(Operation::Update {
45 id: actual.id,
46 name,
47 ruleset,
48 unmanaged_rules: actual.unmanaged_rules.clone(),
49 }),
50 None => Some(Operation::Create { name, ruleset }),
51 };
52 (diff, operation.into_iter().collect())
53 },
54 |ruleset, _| {
55 Some((
56 ruleset.name.clone(),
57 Operation::Delete {
58 id: ruleset.id,
59 name: ruleset.name.clone(),
60 },
61 ))
62 },
63 )
64}
65
66fn compare(desired: &Ruleset, live: Option<&model::Ruleset>) -> FieldDiff {
67 let desired = desired.clone().normalized();
68 let live_definition = live.map(|live| live.definition.clone().normalized());
69 let live_definition = live_definition.as_ref();
70 let mut diff = FieldDiff::default();
71 diff.compare(
72 "target",
73 live_definition.map(|actual| &actual.target),
74 &desired.target,
75 );
76 diff.compare(
77 "enforcement",
78 live_definition.map(|actual| &actual.enforcement),
79 &desired.enforcement,
80 );
81 diff.compare(
82 "include",
83 live_definition.map(|actual| &actual.include),
84 &desired.include,
85 );
86 diff.compare(
87 "exclude",
88 live_definition.map(|actual| &actual.exclude),
89 &desired.exclude,
90 );
91 diff.compare(
92 "bypass_actors",
93 live_definition.map(|actual| &actual.bypass_actors),
94 &desired.bypass_actors,
95 );
96 desired
97 .rules
98 .compare(live_definition.map(|actual| &actual.rules), &mut diff);
99 diff
100}