1pub struct ValidationResult {
2 pub is_valid: bool,
3 pub issues: Vec<String>,
4}
5
6impl Default for ValidationResult {
7 fn default() -> Self {
8 Self::new()
9 }
10}
11
12impl ValidationResult {
13 pub fn new() -> Self {
14 ValidationResult {
15 is_valid: true,
16 issues: Vec::new(),
17 }
18 }
19
20 pub fn add_issue(&mut self, issue: String) {
21 self.is_valid = false;
22 self.issues.push(issue);
23 }
24}
25
26pub mod gitlab {
28 use serde::{Deserialize, Serialize};
29 use std::collections::HashMap;
30
31 #[derive(Debug, Serialize, Deserialize, Clone)]
33 pub struct Pipeline {
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub image: Option<Image>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub variables: Option<HashMap<String, String>>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub stages: Option<Vec<String>>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub before_script: Option<Vec<String>>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub after_script: Option<Vec<String>>,
53
54 #[serde(flatten)]
56 pub jobs: HashMap<String, Job>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub workflow: Option<Workflow>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub include: Option<Vec<Include>>,
65 }
66
67 #[derive(Debug, Serialize, Deserialize, Clone)]
69 pub struct Job {
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub stage: Option<String>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub image: Option<Image>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub script: Option<Vec<String>>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub before_script: Option<Vec<String>>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub after_script: Option<Vec<String>>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub when: Option<String>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub allow_failure: Option<bool>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 pub services: Option<Vec<Service>>,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub tags: Option<Vec<String>>,
105
106 #[serde(skip_serializing_if = "Option::is_none")]
108 pub variables: Option<HashMap<String, String>>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub dependencies: Option<Vec<String>>,
113
114 #[serde(skip_serializing_if = "Option::is_none")]
116 pub artifacts: Option<Artifacts>,
117
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub cache: Option<Cache>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub rules: Option<Vec<Rule>>,
125
126 #[serde(skip_serializing_if = "Option::is_none")]
128 pub only: Option<Only>,
129
130 #[serde(skip_serializing_if = "Option::is_none")]
132 pub except: Option<Except>,
133
134 #[serde(skip_serializing_if = "Option::is_none")]
136 pub retry: Option<Retry>,
137
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub timeout: Option<String>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub parallel: Option<usize>,
145
146 #[serde(skip_serializing_if = "Option::is_none")]
148 pub template: Option<bool>,
149
150 #[serde(skip_serializing_if = "Option::is_none")]
152 pub extends: Option<Vec<String>>,
153 }
154
155 #[derive(Debug, Serialize, Deserialize, Clone)]
157 #[serde(untagged)]
158 pub enum Image {
159 Simple(String),
161 Detailed {
163 name: String,
165 #[serde(skip_serializing_if = "Option::is_none")]
167 entrypoint: Option<Vec<String>>,
168 },
169 }
170
171 #[derive(Debug, Serialize, Deserialize, Clone)]
173 #[serde(untagged)]
174 pub enum Service {
175 Simple(String),
177 Detailed {
179 name: String,
181 #[serde(skip_serializing_if = "Option::is_none")]
183 command: Option<Vec<String>>,
184 #[serde(skip_serializing_if = "Option::is_none")]
186 entrypoint: Option<Vec<String>>,
187 },
188 }
189
190 #[derive(Debug, Serialize, Deserialize, Clone)]
192 pub struct Artifacts {
193 #[serde(skip_serializing_if = "Option::is_none")]
195 pub paths: Option<Vec<String>>,
196 #[serde(skip_serializing_if = "Option::is_none")]
198 pub expire_in: Option<String>,
199 #[serde(skip_serializing_if = "Option::is_none")]
201 pub when: Option<String>,
202 }
203
204 #[derive(Debug, Serialize, Deserialize, Clone)]
206 pub struct Cache {
207 #[serde(skip_serializing_if = "Option::is_none")]
209 pub key: Option<String>,
210 #[serde(skip_serializing_if = "Option::is_none")]
212 pub paths: Option<Vec<String>>,
213 #[serde(skip_serializing_if = "Option::is_none")]
215 pub when: Option<String>,
216 #[serde(skip_serializing_if = "Option::is_none")]
218 pub policy: Option<String>,
219 }
220
221 #[derive(Debug, Serialize, Deserialize, Clone)]
223 pub struct Rule {
224 #[serde(skip_serializing_if = "Option::is_none")]
226 pub if_: Option<String>,
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub when: Option<String>,
230 #[serde(skip_serializing_if = "Option::is_none")]
232 pub variables: Option<HashMap<String, String>>,
233 }
234
235 #[derive(Debug, Serialize, Deserialize, Clone)]
237 #[serde(untagged)]
238 pub enum Only {
239 Refs(Vec<String>),
241 Complex {
243 #[serde(skip_serializing_if = "Option::is_none")]
245 refs: Option<Vec<String>>,
246 #[serde(skip_serializing_if = "Option::is_none")]
248 branches: Option<Vec<String>>,
249 #[serde(skip_serializing_if = "Option::is_none")]
251 tags: Option<Vec<String>>,
252 #[serde(skip_serializing_if = "Option::is_none")]
254 variables: Option<Vec<String>>,
255 #[serde(skip_serializing_if = "Option::is_none")]
257 changes: Option<Vec<String>>,
258 },
259 }
260
261 #[derive(Debug, Serialize, Deserialize, Clone)]
263 #[serde(untagged)]
264 pub enum Except {
265 Refs(Vec<String>),
267 Complex {
269 #[serde(skip_serializing_if = "Option::is_none")]
271 refs: Option<Vec<String>>,
272 #[serde(skip_serializing_if = "Option::is_none")]
274 branches: Option<Vec<String>>,
275 #[serde(skip_serializing_if = "Option::is_none")]
277 tags: Option<Vec<String>>,
278 #[serde(skip_serializing_if = "Option::is_none")]
280 variables: Option<Vec<String>>,
281 #[serde(skip_serializing_if = "Option::is_none")]
283 changes: Option<Vec<String>>,
284 },
285 }
286
287 #[derive(Debug, Serialize, Deserialize, Clone)]
289 pub struct Workflow {
290 pub rules: Vec<Rule>,
292 }
293
294 #[derive(Debug, Serialize, Deserialize, Clone)]
296 #[serde(untagged)]
297 pub enum Retry {
298 MaxAttempts(u32),
300 Detailed {
302 max: u32,
304 #[serde(skip_serializing_if = "Option::is_none")]
306 when: Option<Vec<String>>,
307 },
308 }
309
310 #[derive(Debug, Serialize, Deserialize, Clone)]
312 #[serde(untagged)]
313 pub enum Include {
314 Local(String),
316 Detailed {
318 #[serde(skip_serializing_if = "Option::is_none")]
320 local: Option<String>,
321 #[serde(skip_serializing_if = "Option::is_none")]
323 remote: Option<String>,
324 #[serde(skip_serializing_if = "Option::is_none")]
326 project: Option<String>,
327 #[serde(skip_serializing_if = "Option::is_none")]
329 file: Option<String>,
330 #[serde(skip_serializing_if = "Option::is_none")]
332 template: Option<String>,
333 #[serde(skip_serializing_if = "Option::is_none")]
335 ref_: Option<String>,
336 },
337 }
338}