wdl_format/v1/
workflow.rs1pub mod call;
4
5use wdl_ast::SyntaxKind;
6use wdl_ast::Token;
7
8use crate::PreToken;
9use crate::TokenStream;
10use crate::Trivia;
11use crate::Writable as _;
12use crate::element::FormatElement;
13
14pub fn format_conditional_statement(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
20 for child in element.children().expect("conditional statement children") {
21 (&child).write(stream);
22 }
23}
24
25pub fn format_conditional_statement_clause(
27 element: &FormatElement,
28 stream: &mut TokenStream<PreToken>,
29) {
30 let mut children = element
31 .children()
32 .expect("conditional statement clause children")
33 .peekable();
34
35 while let Some(el) = children.peek() {
36 let Some(token) = el.element().as_token() else {
39 break;
40 };
41
42 match token {
44 Token::IfKeyword(_) => {
45 el.write(stream);
46 }
47 Token::ElseKeyword(_) => {
48 el.write(stream);
49 }
50 _ => break,
51 }
52
53 children.next();
55 }
56 stream.end_word();
57
58 let open_paren = children.next().expect("open paren");
59 assert!(open_paren.element().kind() == SyntaxKind::OpenParen);
60 (&open_paren).write(stream);
61
62 for child in children.by_ref() {
63 (&child).write(stream);
64 if child.element().kind() == SyntaxKind::CloseParen {
65 stream.end_word();
66 break;
67 }
68 }
69
70 let open_brace = children.next().expect("open brace");
71 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
72 (&open_brace).write(stream);
73 stream.increment_indent();
74
75 for child in children {
76 if child.element().kind() == SyntaxKind::CloseBrace {
77 stream.decrement_indent();
78 }
79 (&child).write(stream);
80 }
81 stream.end_line();
82}
83
84pub fn format_scatter_statement(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
90 let mut children = element.children().expect("scatter statement children");
91
92 let scatter_keyword = children.next().expect("scatter keyword");
93 assert!(scatter_keyword.element().kind() == SyntaxKind::ScatterKeyword);
94 (&scatter_keyword).write(stream);
95 stream.end_word();
96
97 let open_paren = children.next().expect("open paren");
98 assert!(open_paren.element().kind() == SyntaxKind::OpenParen);
99 (&open_paren).write(stream);
100
101 let variable = children.next().expect("scatter variable");
102 assert!(variable.element().kind() == SyntaxKind::Ident);
103 (&variable).write(stream);
104 stream.end_word();
105
106 let in_keyword = children.next().expect("in keyword");
107 assert!(in_keyword.element().kind() == SyntaxKind::InKeyword);
108 (&in_keyword).write(stream);
109 stream.end_word();
110
111 for child in children.by_ref() {
112 (&child).write(stream);
113 if child.element().kind() == SyntaxKind::CloseParen {
114 stream.end_word();
115 break;
116 }
117 }
118
119 let open_brace = children.next().expect("open brace");
120 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
121 (&open_brace).write(stream);
122 stream.end_line();
123 stream.increment_indent();
124
125 for child in children {
126 if child.element().kind() == SyntaxKind::CloseBrace {
127 stream.decrement_indent();
128 }
129 (&child).write(stream);
130 }
131 stream.end_line();
132}
133
134pub fn format_workflow_definition(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
140 let mut children = element.children().expect("workflow definition children");
141
142 stream.ignore_trailing_blank_lines();
143
144 let workflow_keyword = children.next().expect("workflow keyword");
145 assert!(workflow_keyword.element().kind() == SyntaxKind::WorkflowKeyword);
146 (&workflow_keyword).write(stream);
147 stream.end_word();
148
149 let name = children.next().expect("workflow name");
150 assert!(name.element().kind() == SyntaxKind::Ident);
151 (&name).write(stream);
152 stream.end_word();
153
154 let open_brace = children.next().expect("open brace");
155 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
156 (&open_brace).write(stream);
157 stream.increment_indent();
158
159 let mut meta = None;
160 let mut parameter_meta = None;
161 let mut input = None;
162 let mut body = Vec::new();
163 let mut output = None;
164 let mut hints = None;
165 let mut close_brace = None;
166
167 for child in children {
168 match child.element().kind() {
169 SyntaxKind::MetadataSectionNode => {
170 meta = Some(child.clone());
171 }
172 SyntaxKind::ParameterMetadataSectionNode => {
173 parameter_meta = Some(child.clone());
174 }
175 SyntaxKind::InputSectionNode => {
176 input = Some(child.clone());
177 }
178 SyntaxKind::BoundDeclNode => {
179 body.push(child.clone());
180 }
181 SyntaxKind::CallStatementNode => {
182 body.push(child.clone());
183 }
184 SyntaxKind::ConditionalStatementNode => {
185 body.push(child.clone());
186 }
187 SyntaxKind::ScatterStatementNode => {
188 body.push(child.clone());
189 }
190 SyntaxKind::OutputSectionNode => {
191 output = Some(child.clone());
192 }
193 SyntaxKind::WorkflowHintsSectionNode => {
194 hints = Some(child.clone());
195 }
196 SyntaxKind::CloseBrace => {
197 close_brace = Some(child.clone());
198 }
199 _ => {
200 unreachable!(
201 "unexpected child in workflow definition: {:?}",
202 child.element().kind()
203 );
204 }
205 }
206 }
207
208 if let Some(meta) = meta {
209 (&meta).write(stream);
210 stream.blank_line();
211 }
212
213 if let Some(parameter_meta) = parameter_meta {
214 (¶meter_meta).write(stream);
215 stream.blank_line();
216 }
217
218 if let Some(input) = input {
219 (&input).write(stream);
220 stream.blank_line();
221 }
222
223 stream.allow_blank_lines();
224 for child in body {
225 (&child).write(stream);
226 }
227 stream.ignore_trailing_blank_lines();
228 stream.blank_line();
229
230 if let Some(output) = output {
231 (&output).write(stream);
232 stream.blank_line();
233 }
234
235 if let Some(hints) = hints {
236 (&hints).write(stream);
237 stream.blank_line();
238 }
239
240 stream.trim_while(|t| matches!(t, PreToken::BlankLine | PreToken::Trivia(Trivia::BlankLine)));
241
242 stream.decrement_indent();
243 (&close_brace.expect("workflow close brace")).write(stream);
244 stream.end_line();
245}
246
247pub fn format_workflow_hints_array(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
253 let mut children = element.children().expect("workflow hints array children");
254
255 let open_bracket = children.next().expect("open bracket");
256 assert!(open_bracket.element().kind() == SyntaxKind::OpenBracket);
257 (&open_bracket).write(stream);
258 stream.increment_indent();
259
260 let mut items = Vec::new();
261 let mut commas = Vec::new();
262 let mut close_bracket = None;
263
264 for child in children {
265 match child.element().kind() {
266 SyntaxKind::Comma => {
267 commas.push(child.clone());
268 }
269 SyntaxKind::CloseBracket => {
270 close_bracket = Some(child.clone());
271 }
272 _ => {
273 items.push(child.clone());
274 }
275 }
276 }
277
278 let mut commas = commas.into_iter();
279 for item in items {
280 (&item).write(stream);
281 match commas.next() {
282 Some(comma) => {
283 (&comma).write(stream);
284 }
285 _ => {
286 stream.push_literal(",".to_string(), SyntaxKind::Comma);
287 }
288 }
289 stream.end_line();
290 }
291
292 stream.decrement_indent();
293 (&close_bracket.expect("workflow hints array close bracket")).write(stream);
294}
295
296pub fn format_workflow_hints_item(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
302 let mut children = element.children().expect("workflow hints item children");
303
304 let key = children.next().expect("workflow hints item key");
305 assert!(key.element().kind() == SyntaxKind::Ident);
306 (&key).write(stream);
307
308 let colon = children.next().expect("workflow hints item colon");
309 assert!(colon.element().kind() == SyntaxKind::Colon);
310 (&colon).write(stream);
311 stream.end_word();
312
313 let value = children.next().expect("workflow hints item value");
314 (&value).write(stream);
315
316 stream.end_line();
317}
318
319pub fn format_workflow_hints_object_item(
325 element: &FormatElement,
326 stream: &mut TokenStream<PreToken>,
327) {
328 let mut children = element
329 .children()
330 .expect("workflow hints object item children");
331
332 let key = children.next().expect("workflow hints object item key");
333 assert!(key.element().kind() == SyntaxKind::Ident);
334 (&key).write(stream);
335
336 let colon = children.next().expect("workflow hints object item colon");
337 assert!(colon.element().kind() == SyntaxKind::Colon);
338 (&colon).write(stream);
339 stream.end_word();
340
341 let value = children.next().expect("workflow hints object item value");
342 (&value).write(stream);
343
344 stream.end_line();
345}
346
347pub fn format_workflow_hints_object(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
353 let mut children = element.children().expect("workflow hints object children");
354
355 let open_brace = children.next().expect("open brace");
356 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
357 (&open_brace).write(stream);
358 stream.increment_indent();
359
360 for child in children {
361 if child.element().kind() == SyntaxKind::CloseBrace {
362 stream.decrement_indent();
363 }
364 (&child).write(stream);
365 stream.end_line();
366 }
367}
368
369pub fn format_workflow_hints_section(element: &FormatElement, stream: &mut TokenStream<PreToken>) {
375 let mut children = element.children().expect("workflow hints section children");
376
377 let hints_keyword = children.next().expect("hints keyword");
378 assert!(hints_keyword.element().kind() == SyntaxKind::HintsKeyword);
379 (&hints_keyword).write(stream);
380 stream.end_word();
381
382 let open_brace = children.next().expect("open brace");
383 assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
384 (&open_brace).write(stream);
385 stream.increment_indent();
386
387 for child in children {
388 if child.element().kind() == SyntaxKind::CloseBrace {
389 stream.decrement_indent();
390 }
391 (&child).write(stream);
392 stream.end_line();
393 }
394}