ephemeris_forge_github/api/model/
repository.rs1use facet::Facet;
2
3use super::Analysis;
4use crate::{
5 MergeCommitMessage, MergeCommitTitle, PullRequestCreationPolicy, Reviewer, ReviewerMode,
6 ReviewerType, SquashMergeCommitMessage, SquashMergeCommitTitle, Status, Visibility,
7};
8
9#[derive(Clone, Copy, Debug, Default, Eq, Facet, PartialEq)]
11pub struct ViewerPermissions {
12 #[facet(default)]
14 pub admin: bool,
15}
16
17#[derive(Clone, Debug, Default, Eq, Facet, PartialEq)]
19#[expect(
20 clippy::struct_excessive_bools,
21 reason = "these are independent GitHub repository switches"
22)]
23pub struct Repository {
24 pub name: String,
26 #[facet(default)]
29 pub description: String,
30 #[facet(default)]
32 pub homepage: String,
33 #[facet(default)]
35 pub visibility: Option<Visibility>,
36 pub topics: Vec<String>,
38 pub archived: bool,
40 pub default_branch: Option<String>,
42 pub allow_merge_commit: bool,
44 pub allow_rebase_merge: bool,
46 pub allow_squash_merge: bool,
48 #[facet(default)]
50 pub allow_auto_merge: bool,
51 pub delete_branch_on_merge: bool,
53 pub allow_update_branch: bool,
55 pub has_issues: bool,
57 pub has_projects: bool,
59 pub has_wiki: bool,
61 #[facet(default = true)]
63 pub has_pull_requests: bool,
64 #[facet(default)]
66 pub has_discussions: bool,
67 #[facet(default)]
69 pub pull_request_creation_policy: PullRequestCreationPolicy,
70 #[facet(default)]
72 pub is_template: bool,
73 #[facet(default)]
75 pub squash_merge_commit_title: SquashMergeCommitTitle,
76 #[facet(default)]
78 pub squash_merge_commit_message: SquashMergeCommitMessage,
79 #[facet(default)]
81 pub merge_commit_title: MergeCommitTitle,
82 #[facet(default)]
84 pub merge_commit_message: MergeCommitMessage,
85 #[facet(default)]
87 pub allow_forking: Option<bool>,
88 #[facet(default)]
90 pub web_commit_signoff_required: bool,
91 #[facet(default)]
93 pub security_and_analysis: Analysis,
94 #[facet(default)]
96 pub permissions: Option<ViewerPermissions>,
97}
98
99#[derive(Clone, Debug, Facet)]
101pub(crate) struct StatusWire {
102 status: Status,
103}
104
105#[derive(Clone, Debug, Facet)]
107pub(crate) struct ReviewerWire {
108 reviewer_id: u64,
109 reviewer_type: ReviewerType,
110 #[facet(default)]
111 mode: Option<ReviewerMode>,
112}
113
114#[derive(Clone, Debug, Default, Facet)]
116pub(crate) struct BypassOptionsWire {
117 #[facet(default)]
118 reviewers: Vec<ReviewerWire>,
119}
120
121#[derive(Clone, Debug, Default, Facet)]
123pub(crate) struct AnalysisWire {
124 #[facet(default)]
125 advanced_security: Option<StatusWire>,
126 #[facet(default)]
127 code_security: Option<StatusWire>,
128 #[facet(default)]
129 secret_scanning: Option<StatusWire>,
130 #[facet(default)]
131 secret_scanning_push_protection: Option<StatusWire>,
132 #[facet(default)]
133 secret_scanning_ai_detection: Option<StatusWire>,
134 #[facet(default)]
135 secret_scanning_non_provider_patterns: Option<StatusWire>,
136 #[facet(default)]
137 secret_scanning_delegated_alert_dismissal: Option<StatusWire>,
138 #[facet(default)]
139 secret_scanning_delegated_bypass: Option<StatusWire>,
140 #[facet(default)]
141 secret_scanning_delegated_bypass_options: Option<BypassOptionsWire>,
142}
143
144impl From<&Analysis> for AnalysisWire {
145 fn from(value: &Analysis) -> Self {
146 let status = |status: Option<Status>| status.map(|status| StatusWire { status });
147 Self {
148 advanced_security: status(value.advanced_security),
149 code_security: status(value.code_security),
150 secret_scanning: status(value.secret_scanning),
151 secret_scanning_push_protection: status(value.secret_scanning_push_protection),
152 secret_scanning_ai_detection: status(value.secret_scanning_ai_detection),
153 secret_scanning_non_provider_patterns: status(
154 value.secret_scanning_non_provider_patterns,
155 ),
156 secret_scanning_delegated_alert_dismissal: status(
157 value.secret_scanning_delegated_alert_dismissal,
158 ),
159 secret_scanning_delegated_bypass: status(value.secret_scanning_delegated_bypass),
160 secret_scanning_delegated_bypass_options: Some(BypassOptionsWire {
161 reviewers: value
162 .secret_scanning_delegated_bypass_reviewers
163 .iter()
164 .map(|reviewer| ReviewerWire {
165 reviewer_id: reviewer.reviewer_id,
166 reviewer_type: reviewer.reviewer_type,
167 mode: Some(reviewer.mode),
168 })
169 .collect(),
170 }),
171 }
172 }
173}
174
175impl From<AnalysisWire> for Analysis {
176 fn from(value: AnalysisWire) -> Self {
177 let status = |wire: Option<StatusWire>| wire.map(|wire| wire.status);
178 let mut reviewers: Vec<Reviewer> = value
179 .secret_scanning_delegated_bypass_options
180 .unwrap_or_default()
181 .reviewers
182 .into_iter()
183 .map(|reviewer| Reviewer {
184 reviewer_id: reviewer.reviewer_id,
185 reviewer_type: reviewer.reviewer_type,
186 mode: reviewer.mode.unwrap_or(ReviewerMode::Always),
187 })
188 .collect();
189 reviewers.sort_unstable();
190 Self {
191 advanced_security: status(value.advanced_security),
192 code_security: status(value.code_security),
193 secret_scanning: status(value.secret_scanning),
194 secret_scanning_push_protection: status(value.secret_scanning_push_protection),
195 secret_scanning_ai_detection: status(value.secret_scanning_ai_detection),
196 secret_scanning_non_provider_patterns: status(
197 value.secret_scanning_non_provider_patterns,
198 ),
199 secret_scanning_delegated_alert_dismissal: status(
200 value.secret_scanning_delegated_alert_dismissal,
201 ),
202 secret_scanning_delegated_bypass: status(value.secret_scanning_delegated_bypass),
203 secret_scanning_delegated_bypass_reviewers: reviewers,
204 }
205 }
206}