ephemeris_forge_github/api/model/
rulesets.rs1mod head;
2
3use ephemeris_forge::Limitation;
4use facet::Facet;
5use facet_value::Value;
6
7use self::head::RuleHead;
8use crate::api::ForgeError;
9use crate::{
10 ActorType, BypassActor, BypassMode, Enforcement, Rules, Ruleset as Definition, Target,
11};
12
13#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct Ruleset {
16 pub id: u64,
18 pub name: String,
20 pub definition: Definition,
22 pub unmanaged_rules: Vec<Value>,
25 pub limitations: Vec<Limitation>,
28}
29
30#[derive(Facet)]
33pub(crate) struct RulesetSummary {
34 pub(crate) id: u64,
35}
36
37#[derive(Default, Facet)]
38pub(crate) struct RulesetConditions {
39 #[facet(default)]
40 ref_name: RefNameCondition,
41}
42
43#[derive(Default, Facet)]
44struct RefNameCondition {
45 #[facet(default)]
46 include: Vec<String>,
47 #[facet(default)]
48 exclude: Vec<String>,
49}
50
51#[derive(Facet)]
52pub(crate) struct BypassActorWire {
53 #[facet(default)]
54 actor_id: Option<i64>,
55 actor_type: ActorType,
56 #[facet(default)]
57 bypass_mode: Option<BypassMode>,
58}
59
60#[derive(Facet)]
62pub(crate) struct RulesetResponse {
63 pub(crate) id: u64,
64 pub(crate) name: String,
65 pub(crate) target: String,
66 pub(crate) enforcement: Enforcement,
67 #[facet(default)]
68 pub(crate) bypass_actors: Vec<BypassActorWire>,
69 #[facet(default)]
70 pub(crate) conditions: RulesetConditions,
71 #[facet(default)]
72 pub(crate) rules: Vec<Value>,
73}
74
75impl TryFrom<RulesetResponse> for Ruleset {
76 type Error = ForgeError;
77
78 fn try_from(value: RulesetResponse) -> Result<Self, ForgeError> {
81 let mut limitations = Vec::new();
82 let mut unmanaged_rules = Vec::new();
83 let mut rules = Rules::none();
84 let name = value.name.as_str();
85 for rule in value.rules {
86 let head = RuleHead::decode(name, &rule)?;
87 if head.kind == "pull_request" && head.has_entries("required_reviewers") {
88 limitations.push(Limitation::RequiredReviewersDropped {
89 ruleset: name.to_owned(),
90 });
91 }
92 if !rules.absorb(&head.kind, &head.decoder(name))? {
93 limitations.push(Limitation::UnmanagedRuleType {
94 ruleset: name.to_owned(),
95 kind: head.kind.clone(),
96 });
97 unmanaged_rules.push(rule);
98 }
99 }
100 Ok(Self {
101 id: value.id,
102 definition: Definition {
103 target: Target::observed(&value.target),
104 enforcement: value.enforcement,
105 include: value.conditions.ref_name.include,
106 exclude: value.conditions.ref_name.exclude,
107 bypass_actors: value
108 .bypass_actors
109 .into_iter()
110 .map(|actor| BypassActor {
111 actor_type: actor.actor_type,
112 actor_id: actor.actor_id,
113 bypass_mode: actor.bypass_mode.unwrap_or(BypassMode::Always),
114 })
115 .collect(),
116 rules,
117 },
118 name: value.name,
119 unmanaged_rules,
120 limitations,
121 })
122 }
123}