ephemeris_forge/report.rs
1use std::collections::BTreeMap;
2
3use crate::{Change, Limitation, Lockout};
4
5/// The plan result used by both text and machine reports.
6#[derive(Clone, Debug, Default)]
7pub struct Report {
8 /// Fields that would change, grouped by resource name.
9 pub changes: BTreeMap<String, Change>,
10 /// Fields that already match, grouped by resource name.
11 pub unchanged: BTreeMap<String, Vec<String>>,
12 /// A plan can be inspected but not applied when archived.
13 pub archived: bool,
14 /// Whether the caller administers the repository, when the forge says.
15 pub admin: Option<bool>,
16 /// Which rule governs the default branch, on forges where rule order
17 /// decides.
18 pub governance: Option<Shadowing>,
19 /// Access or settings that the forge exposes but this tool cannot change.
20 pub limitations: Vec<Limitation>,
21 /// Grants carrying the caller's own access that the plan would remove.
22 pub lockouts: Vec<Lockout>,
23}
24
25impl Report {
26 /// Note that `resource` would be deleted.
27 pub fn record_delete(&mut self, resource: String) {
28 self.changes.insert(resource, Change::Delete);
29 }
30}
31
32/// Effective protection of the default branch.
33#[derive(Clone, Debug, Eq, PartialEq)]
34pub struct Shadowing {
35 /// The branch this observation concerns.
36 pub default_branch: String,
37 /// The first matching rule in the forge's response order.
38 pub governing_rule: Option<String>,
39 /// Whether the governing rule is declared by the configuration.
40 pub declared: bool,
41}
42
43impl Shadowing {
44 /// Whether an undeclared rule overrides the desired configuration.
45 #[must_use]
46 pub const fn is_shadowed(&self) -> bool {
47 self.governing_rule.is_some() && !self.declared
48 }
49}