Skip to main content

wdl_format/v1/
expr.rs

1//! Formatting of WDL v1.x expression elements.
2
3use wdl_ast::SyntaxKind;
4
5use crate::Config;
6use crate::PreToken;
7use crate::TokenStream;
8use crate::Writable as _;
9use crate::element::FormatElement;
10
11/// Formats a [`SepOption`](wdl_ast::v1::SepOption).
12///
13/// # Panics
14///
15/// This will panic if the element does not have the expected children.
16pub fn format_sep_option(
17    element: &FormatElement,
18    stream: &mut TokenStream<PreToken>,
19    config: &Config,
20) {
21    let mut children = element.children().expect("sep option children");
22
23    let sep_keyword = children.next().expect("sep keyword");
24    assert!(sep_keyword.element().kind() == SyntaxKind::Ident);
25    (&sep_keyword).write(stream, config);
26
27    let equals = children.next().expect("sep equals");
28    assert!(equals.element().kind() == SyntaxKind::Assignment);
29    (&equals).write(stream, config);
30
31    let sep_value = children.next().expect("sep value");
32    assert!(sep_value.element().kind() == SyntaxKind::LiteralStringNode);
33    (&sep_value).write(stream, config);
34    stream.end_word();
35}
36
37/// Formats a [`DefaultOption`](wdl_ast::v1::DefaultOption).
38///
39/// # Panics
40///
41/// This will panic if the element does not have the expected children.
42pub fn format_default_option(
43    element: &FormatElement,
44    stream: &mut TokenStream<PreToken>,
45    config: &Config,
46) {
47    let mut children = element.children().expect("default option children");
48
49    let default_keyword = children.next().expect("default keyword");
50    assert!(default_keyword.element().kind() == SyntaxKind::Ident);
51    (&default_keyword).write(stream, config);
52
53    let equals = children.next().expect("default equals");
54    assert!(equals.element().kind() == SyntaxKind::Assignment);
55    (&equals).write(stream, config);
56
57    let default_value = children.next().expect("default value");
58    (&default_value).write(stream, config);
59    stream.end_word();
60}
61
62/// Formats a [`TrueFalseOption`](wdl_ast::v1::TrueFalseOption).
63///
64/// # Panics
65///
66/// This will panic if the element does not have the expected children.
67pub fn format_true_false_option(
68    element: &FormatElement,
69    stream: &mut TokenStream<PreToken>,
70    config: &Config,
71) {
72    let mut children = element.children().expect("true false option children");
73
74    let first_keyword = children.next().expect("true false option first keyword");
75    let first_keyword_kind = first_keyword.element().kind();
76    assert!(
77        first_keyword_kind == SyntaxKind::TrueKeyword
78            || first_keyword_kind == SyntaxKind::FalseKeyword
79    );
80
81    let first_equals = children.next().expect("true false option first equals");
82    assert!(first_equals.element().kind() == SyntaxKind::Assignment);
83
84    let first_value = children.next().expect("true false option first value");
85
86    let second_keyword = children.next().expect("true false option second keyword");
87    let second_keyword_kind = second_keyword.element().kind();
88    assert!(
89        second_keyword_kind == SyntaxKind::TrueKeyword
90            || second_keyword_kind == SyntaxKind::FalseKeyword
91    );
92
93    let second_equals = children.next().expect("true false option second equals");
94    assert!(second_equals.element().kind() == SyntaxKind::Assignment);
95
96    let second_value = children.next().expect("true false option second value");
97
98    if first_keyword_kind == SyntaxKind::TrueKeyword {
99        assert!(second_keyword_kind == SyntaxKind::FalseKeyword);
100        (&first_keyword).write(stream, config);
101        (&first_equals).write(stream, config);
102        (&first_value).write(stream, config);
103        stream.end_word();
104        (&second_keyword).write(stream, config);
105        (&second_equals).write(stream, config);
106        (&second_value).write(stream, config);
107    } else {
108        assert!(second_keyword_kind == SyntaxKind::TrueKeyword);
109        (&second_keyword).write(stream, config);
110        (&second_equals).write(stream, config);
111        (&second_value).write(stream, config);
112        stream.end_word();
113        (&first_keyword).write(stream, config);
114        (&first_equals).write(stream, config);
115        (&first_value).write(stream, config);
116    }
117    stream.end_word();
118}
119
120/// Formats a [`Placeholder`](wdl_ast::v1::Placeholder).
121///
122/// # Panics
123///
124/// This will panic if the element does not have the expected children.
125pub fn format_placeholder(
126    element: &FormatElement,
127    stream: &mut TokenStream<PreToken>,
128    config: &Config,
129) {
130    let mut children = element.children().expect("placeholder children");
131
132    let open = children.next().expect("placeholder open");
133    assert!(open.element().kind() == SyntaxKind::PlaceholderOpen);
134    let syntax = open.element().inner();
135    let text = syntax.as_token().expect("token").text();
136    match text {
137        "${" => {
138            stream.push_literal_in_place_of_token(
139                open.element().as_token().expect("token"),
140                "~{".to_owned(),
141            );
142        }
143        "~{" => {
144            (&open).write(stream, config);
145        }
146        _ => {
147            unreachable!("unexpected placeholder open: {:?}", text);
148        }
149    }
150
151    for child in children {
152        (&child).write(stream, config);
153    }
154}
155
156/// Formats a [`LiteralString`](wdl_ast::v1::LiteralString).
157///
158/// # Panics
159///
160/// This will panic if the element does not have the expected children.
161pub fn format_literal_string(
162    element: &FormatElement,
163    stream: &mut TokenStream<PreToken>,
164    config: &Config,
165) {
166    for child in element.children().expect("literal string children") {
167        match child.element().kind() {
168            SyntaxKind::SingleQuote => {
169                stream.push_literal_in_place_of_token(
170                    child.element().as_token().expect("token"),
171                    "\"".to_owned(),
172                );
173            }
174            SyntaxKind::OpenHeredoc | SyntaxKind::CloseHeredoc | SyntaxKind::DoubleQuote => {
175                (&child).write(stream, config);
176            }
177            SyntaxKind::LiteralStringText => {
178                let mut replacement = String::new();
179                let syntax = child.element().inner();
180                let mut chars = syntax.as_token().expect("token").text().chars().peekable();
181                let mut prev_c = None;
182                while let Some(c) = chars.next() {
183                    match c {
184                        '\\' => {
185                            if let Some(next_c) = chars.peek()
186                                && *next_c == '\''
187                            {
188                                // Do not write this backslash as single quotes don't need
189                                // escaping in a double-quoted string (and we format all
190                                // LiteralStrings as double-quoted strings).
191                                prev_c = Some(c);
192                                continue;
193                            }
194                            replacement.push(c);
195                        }
196                        '"' => {
197                            if prev_c.is_none_or(|c| c != '\\') {
198                                // This double quote sign is not escaped, so we need to escape
199                                // it. This happens when a single quoted string is re-formatted
200                                // as a double quoted string.
201                                replacement.push('\\');
202                            }
203                            replacement.push(c);
204                        }
205                        _ => {
206                            replacement.push(c);
207                        }
208                    }
209                    prev_c = Some(c);
210                }
211
212                stream.push_literal_in_place_of_token(
213                    child.element().as_token().expect("token"),
214                    replacement,
215                );
216            }
217            SyntaxKind::PlaceholderNode => {
218                (&child).write(stream, config);
219            }
220            _ => {
221                unreachable!(
222                    "unexpected child in literal string: {:?}",
223                    child.element().kind()
224                );
225            }
226        }
227    }
228}
229
230/// Formats a [`LiteralNone`](wdl_ast::v1::LiteralNone).
231///
232/// # Panics
233///
234/// This will panic if the element does not have the expected children.
235pub fn format_literal_none(
236    element: &FormatElement,
237    stream: &mut TokenStream<PreToken>,
238    config: &Config,
239) {
240    let mut children = element.children().expect("literal none children");
241    let none = children.next().expect("literal none token");
242    assert!(none.element().kind() == SyntaxKind::NoneKeyword);
243    (&none).write(stream, config);
244}
245
246/// Formats a [`LiteralPair`](wdl_ast::v1::LiteralPair).
247///
248/// # Panics
249///
250/// This will panic if the element does not have the expected children.
251pub fn format_literal_pair(
252    element: &FormatElement,
253    stream: &mut TokenStream<PreToken>,
254    config: &Config,
255) {
256    let mut children = element.children().expect("literal pair children");
257
258    let open_paren = children.next().expect("literal pair open paren");
259    assert!(open_paren.element().kind() == SyntaxKind::OpenParen);
260    (&open_paren).write(stream, config);
261
262    let left = children.next().expect("literal pair left");
263    (&left).write(stream, config);
264
265    let comma = children.next().expect("literal pair comma");
266    assert!(comma.element().kind() == SyntaxKind::Comma);
267    (&comma).write(stream, config);
268    stream.end_word();
269
270    let right = children.next().expect("literal pair right");
271    (&right).write(stream, config);
272
273    let close_paren = children.next().expect("literal pair close paren");
274    assert!(close_paren.element().kind() == SyntaxKind::CloseParen);
275    (&close_paren).write(stream, config);
276}
277
278/// Formats a [`LiteralBoolean`](wdl_ast::v1::LiteralBoolean).
279///
280/// # Panics
281///
282/// This will panic if the element does not have the expected children.
283pub fn format_literal_boolean(
284    element: &FormatElement,
285    stream: &mut TokenStream<PreToken>,
286    config: &Config,
287) {
288    let mut children = element.children().expect("literal boolean children");
289    let bool = children.next().expect("literal boolean token");
290    (&bool).write(stream, config);
291}
292
293/// Formats a [`NegationExpr`](wdl_ast::v1::NegationExpr).
294///
295/// # Panics
296///
297/// This will panic if the element does not have the expected children.
298pub fn format_negation_expr(
299    element: &FormatElement,
300    stream: &mut TokenStream<PreToken>,
301    config: &Config,
302) {
303    let mut children = element.children().expect("negation expr children");
304    let minus = children.next().expect("negation expr minus");
305    assert!(minus.element().kind() == SyntaxKind::Minus);
306    (&minus).write(stream, config);
307
308    let expr = children.next().expect("negation expr expr");
309    (&expr).write(stream, config);
310}
311
312/// Formats a [`LiteralInteger`](wdl_ast::v1::LiteralInteger).
313///
314/// # Panics
315///
316/// This will panic if the element does not have the expected children.
317pub fn format_literal_integer(
318    element: &FormatElement,
319    stream: &mut TokenStream<PreToken>,
320    config: &Config,
321) {
322    for child in element.children().expect("literal integer children") {
323        (&child).write(stream, config);
324    }
325}
326
327/// Formats a [`LiteralFloat`](wdl_ast::v1::LiteralFloat).
328///
329/// # Panics
330///
331/// This will panic if the element does not have the expected children.
332pub fn format_literal_float(
333    element: &FormatElement,
334    stream: &mut TokenStream<PreToken>,
335    config: &Config,
336) {
337    for child in element.children().expect("literal float children") {
338        (&child).write(stream, config);
339    }
340}
341
342/// Formats a [`NameRefExpr`](wdl_ast::v1::NameRefExpr).
343///
344/// # Panics
345///
346/// This will panic if the element does not have the expected children.
347pub fn format_name_ref_expr(
348    element: &FormatElement,
349    stream: &mut TokenStream<PreToken>,
350    config: &Config,
351) {
352    let mut children = element.children().expect("name ref children");
353    let name = children.next().expect("name ref name");
354    (&name).write(stream, config);
355}
356
357/// Formats a [`LiteralArray`](wdl_ast::v1::LiteralArray).
358///
359/// # Panics
360///
361/// This will panic if the element does not have the expected children.
362pub fn format_literal_array(
363    element: &FormatElement,
364    stream: &mut TokenStream<PreToken>,
365    config: &Config,
366) {
367    let mut children = element.children().expect("literal array children");
368
369    let open_bracket = children.next().expect("literal array open bracket");
370    assert!(open_bracket.element().kind() == SyntaxKind::OpenBracket);
371    (&open_bracket).write(stream, config);
372
373    let mut items = Vec::new();
374    let mut commas = Vec::new();
375    let mut close_bracket = None;
376
377    for child in children {
378        match child.element().kind() {
379            SyntaxKind::CloseBracket => {
380                close_bracket = Some(child.to_owned());
381            }
382            SyntaxKind::Comma => {
383                commas.push(child.to_owned());
384            }
385            _ => {
386                items.push(child.to_owned());
387            }
388        }
389    }
390
391    let empty = items.is_empty();
392    if !empty {
393        stream.increment_indent();
394    }
395    let mut commas = commas.iter();
396    for item in items {
397        (&item).write(stream, config);
398        if let Some(comma) = commas.next() {
399            (comma).write(stream, config);
400        } else if config.trailing_commas {
401            stream.push_literal(",".to_string(), SyntaxKind::Comma);
402        }
403        stream.end_line();
404    }
405
406    if !empty {
407        stream.decrement_indent();
408    }
409    (&close_bracket.expect("literal array close bracket")).write(stream, config);
410}
411
412/// Formats a [`LiteralMapItem`](wdl_ast::v1::LiteralMapItem).
413///
414/// # Panics
415///
416/// This will panic if the element does not have the expected children.
417pub fn format_literal_map_item(
418    element: &FormatElement,
419    stream: &mut TokenStream<PreToken>,
420    config: &Config,
421) {
422    let mut children = element.children().expect("literal map item children");
423
424    let key = children.next().expect("literal map item key");
425    (&key).write(stream, config);
426
427    let colon = children.next().expect("literal map item colon");
428    assert!(colon.element().kind() == SyntaxKind::Colon);
429    (&colon).write(stream, config);
430    stream.end_word();
431
432    let value = children.next().expect("literal map item value");
433    (&value).write(stream, config);
434}
435
436/// Formats a [`LiteralMap`](wdl_ast::v1::LiteralMap).
437///
438/// # Panics
439///
440/// This will panic if the element does not have the expected children.
441pub fn format_literal_map(
442    element: &FormatElement,
443    stream: &mut TokenStream<PreToken>,
444    config: &Config,
445) {
446    let mut children = element.children().expect("literal map children");
447
448    let open_brace = children.next().expect("literal map open brace");
449    assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
450    (&open_brace).write(stream, config);
451    stream.increment_indent();
452
453    let mut items = Vec::new();
454    let mut commas = Vec::new();
455    let mut close_brace = None;
456
457    for child in children {
458        match child.element().kind() {
459            SyntaxKind::CloseBrace => {
460                close_brace = Some(child.to_owned());
461            }
462            SyntaxKind::Comma => {
463                commas.push(child.to_owned());
464            }
465            _ => {
466                items.push(child.to_owned());
467            }
468        }
469    }
470
471    let mut commas = commas.iter();
472    for item in items {
473        (&item).write(stream, config);
474        if let Some(comma) = commas.next() {
475            (comma).write(stream, config);
476        } else if config.trailing_commas {
477            stream.push_literal(",".to_string(), SyntaxKind::Comma);
478        }
479        stream.end_line();
480    }
481
482    stream.decrement_indent();
483    (&close_brace.expect("literal map close brace")).write(stream, config);
484}
485
486/// Formats a [`LiteralObjectItem`](wdl_ast::v1::LiteralObjectItem).
487///
488/// # Panics
489///
490/// This will panic if the element does not have the expected children.
491pub fn format_literal_object_item(
492    element: &FormatElement,
493    stream: &mut TokenStream<PreToken>,
494    config: &Config,
495) {
496    let mut children = element.children().expect("literal object item children");
497
498    let key = children.next().expect("literal object item key");
499    assert!(key.element().kind() == SyntaxKind::Ident);
500    (&key).write(stream, config);
501
502    let colon = children.next().expect("literal object item colon");
503    assert!(colon.element().kind() == SyntaxKind::Colon);
504    (&colon).write(stream, config);
505    stream.end_word();
506
507    let value = children.next().expect("literal object item value");
508    (&value).write(stream, config);
509    assert!(children.next().is_none());
510}
511
512/// Formats a [`LiteralObject`](wdl_ast::v1::LiteralObject).
513///
514/// # Panics
515///
516/// This will panic if the element does not have the expected children.
517pub fn format_literal_object(
518    element: &FormatElement,
519    stream: &mut TokenStream<PreToken>,
520    config: &Config,
521) {
522    let mut children = element.children().expect("literal object children");
523
524    let object_keyword = children.next().expect("literal object keyword");
525    assert!(object_keyword.element().kind() == SyntaxKind::ObjectKeyword);
526    (&object_keyword).write(stream, config);
527    stream.end_word();
528
529    let open_brace = children.next().expect("literal object open brace");
530    assert!(open_brace.element().kind() == SyntaxKind::OpenBrace);
531    (&open_brace).write(stream, config);
532    stream.increment_indent();
533
534    let mut members = Vec::new();
535    let mut commas = Vec::new();
536    let mut close_brace = None;
537
538    for child in children {
539        match child.element().kind() {
540            SyntaxKind::CloseBrace => {
541                close_brace = Some(child.to_owned());
542            }
543            SyntaxKind::Comma => {
544                commas.push(child.to_owned());
545            }
546            _ => {
547                members.push(child.to_owned());
548            }
549        }
550    }
551
552    let mut commas = commas.iter();
553    for member in members {
554        (&member).write(stream, config);
555        if let Some(comma) = commas.next() {
556            (comma).write(stream, config);
557        } else if config.trailing_commas {
558            stream.push_literal(",".to_string(), SyntaxKind::Comma);
559        }
560        stream.end_line();
561    }
562
563    stream.decrement_indent();
564    (&close_brace.expect("literal object close brace")).write(stream, config);
565}
566
567/// Formats a [`AccessExpr`](wdl_ast::v1::AccessExpr).
568///
569/// # Panics
570///
571/// This will panic if the element does not have the expected children.
572pub fn format_access_expr(
573    element: &FormatElement,
574    stream: &mut TokenStream<PreToken>,
575    config: &Config,
576) {
577    for child in element.children().expect("access expr children") {
578        (&child).write(stream, config);
579    }
580}
581
582/// Formats a [`CallExpr`](wdl_ast::v1::CallExpr).
583///
584/// # Panics
585///
586/// This will panic if the element does not have the expected children.
587pub fn format_call_expr(
588    element: &FormatElement,
589    stream: &mut TokenStream<PreToken>,
590    config: &Config,
591) {
592    for child in element.children().expect("call expr children") {
593        (&child).write(stream, config);
594        if child.element().kind() == SyntaxKind::Comma {
595            stream.end_word();
596        }
597    }
598}
599
600/// Formats an [`IndexExpr`](wdl_ast::v1::IndexExpr).
601///
602/// # Panics
603///
604/// This will panic if the element does not have the expected children.
605pub fn format_index_expr(
606    element: &FormatElement,
607    stream: &mut TokenStream<PreToken>,
608    config: &Config,
609) {
610    for child in element.children().expect("index expr children") {
611        (&child).write(stream, config);
612    }
613}
614
615/// Formats an [`AdditionExpr`](wdl_ast::v1::AdditionExpr).
616///
617/// # Panics
618///
619/// This will panic if the element does not have the expected children.
620pub fn format_addition_expr(
621    element: &FormatElement,
622    stream: &mut TokenStream<PreToken>,
623    config: &Config,
624) {
625    for child in element.children().expect("addition expr children") {
626        let whitespace_wrapped = child.element().kind() == SyntaxKind::Plus;
627        if whitespace_wrapped {
628            stream.end_word();
629        }
630        (&child).write(stream, config);
631        if whitespace_wrapped {
632            stream.end_word();
633        }
634    }
635}
636
637/// Formats a [`SubtractionExpr`](wdl_ast::v1::SubtractionExpr).
638///
639/// # Panics
640///
641/// This will panic if the element does not have the expected children.
642pub fn format_subtraction_expr(
643    element: &FormatElement,
644    stream: &mut TokenStream<PreToken>,
645    config: &Config,
646) {
647    for child in element.children().expect("subtraction expr children") {
648        let whitespace_wrapped = child.element().kind() == SyntaxKind::Minus;
649        if whitespace_wrapped {
650            stream.end_word();
651        }
652        (&child).write(stream, config);
653        if whitespace_wrapped {
654            stream.end_word();
655        }
656    }
657}
658
659/// Formats a [`MultiplicationExpr`](wdl_ast::v1::MultiplicationExpr).
660///
661/// # Panics
662///
663/// This will panic if the element does not have the expected children.
664pub fn format_multiplication_expr(
665    element: &FormatElement,
666    stream: &mut TokenStream<PreToken>,
667    config: &Config,
668) {
669    for child in element.children().expect("multiplication expr children") {
670        let whitespace_wrapped = child.element().kind() == SyntaxKind::Asterisk;
671        if whitespace_wrapped {
672            stream.end_word();
673        }
674        (&child).write(stream, config);
675        if whitespace_wrapped {
676            stream.end_word();
677        }
678    }
679}
680
681/// Formats a [`DivisionExpr`](wdl_ast::v1::DivisionExpr).
682///
683/// # Panics
684///
685/// This will panic if the element does not have the expected children.
686pub fn format_division_expr(
687    element: &FormatElement,
688    stream: &mut TokenStream<PreToken>,
689    config: &Config,
690) {
691    for child in element.children().expect("division expr children") {
692        let whitespace_wrapped = child.element().kind() == SyntaxKind::Slash;
693        if whitespace_wrapped {
694            stream.end_word();
695        }
696        (&child).write(stream, config);
697        if whitespace_wrapped {
698            stream.end_word();
699        }
700    }
701}
702
703/// Formats a [`ModuloExpr`](wdl_ast::v1::ModuloExpr).
704///
705/// # Panics
706///
707/// This will panic if the element does not have the expected children.
708pub fn format_modulo_expr(
709    element: &FormatElement,
710    stream: &mut TokenStream<PreToken>,
711    config: &Config,
712) {
713    for child in element.children().expect("modulo expr children") {
714        let whitespace_wrapped = child.element().kind() == SyntaxKind::Percent;
715        if whitespace_wrapped {
716            stream.end_word();
717        }
718        (&child).write(stream, config);
719        if whitespace_wrapped {
720            stream.end_word();
721        }
722    }
723}
724
725/// Formats an [`ExponentiationExpr`](wdl_ast::v1::ExponentiationExpr).
726///
727/// # Panics
728///
729/// This will panic if the element does not have the expected children.
730pub fn format_exponentiation_expr(
731    element: &FormatElement,
732    stream: &mut TokenStream<PreToken>,
733    config: &Config,
734) {
735    for child in element.children().expect("exponentiation expr children") {
736        let whitespace_wrapped = child.element().kind() == SyntaxKind::Exponentiation;
737        if whitespace_wrapped {
738            stream.end_word();
739        }
740        (&child).write(stream, config);
741        if whitespace_wrapped {
742            stream.end_word();
743        }
744    }
745}
746
747/// Formats a [`LogicalAndExpr`](wdl_ast::v1::LogicalAndExpr).
748///
749/// # Panics
750///
751/// This will panic if the element does not have the expected children.
752pub fn format_logical_and_expr(
753    element: &FormatElement,
754    stream: &mut TokenStream<PreToken>,
755    config: &Config,
756) {
757    for child in element.children().expect("logical and expr children") {
758        let whitespace_wrapped = child.element().kind() == SyntaxKind::LogicalAnd;
759        if whitespace_wrapped {
760            stream.end_word();
761        }
762        (&child).write(stream, config);
763        if whitespace_wrapped {
764            stream.end_word();
765        }
766    }
767}
768
769/// Formats a [`LogicalNotExpr`](wdl_ast::v1::LogicalNotExpr).
770///
771/// # Panics
772///
773/// This will panic if the element does not have the expected children.
774pub fn format_logical_not_expr(
775    element: &FormatElement,
776    stream: &mut TokenStream<PreToken>,
777    config: &Config,
778) {
779    let mut children = element.children().expect("logical not expr children");
780    let not = children.next().expect("logical not expr not");
781    assert!(not.element().kind() == SyntaxKind::Exclamation);
782    (&not).write(stream, config);
783
784    let expr = children.next().expect("logical not expr expr");
785    (&expr).write(stream, config);
786}
787
788/// Formats a [`LogicalOrExpr`](wdl_ast::v1::LogicalOrExpr).
789///
790/// # Panics
791///
792/// This will panic if the element does not have the expected children.
793pub fn format_logical_or_expr(
794    element: &FormatElement,
795    stream: &mut TokenStream<PreToken>,
796    config: &Config,
797) {
798    for child in element.children().expect("logical or expr children") {
799        let whitespace_wrapped = child.element().kind() == SyntaxKind::LogicalOr;
800        if whitespace_wrapped {
801            stream.end_word();
802        }
803        (&child).write(stream, config);
804        if whitespace_wrapped {
805            stream.end_word();
806        }
807    }
808}
809
810/// Formats an [`EqualityExpr`](wdl_ast::v1::EqualityExpr).
811///
812/// # Panics
813///
814/// This will panic if the element does not have the expected children.
815pub fn format_equality_expr(
816    element: &FormatElement,
817    stream: &mut TokenStream<PreToken>,
818    config: &Config,
819) {
820    for child in element.children().expect("equality expr children") {
821        let whitespace_wrapped = child.element().kind() == SyntaxKind::Equal;
822        if whitespace_wrapped {
823            stream.end_word();
824        }
825        (&child).write(stream, config);
826        if whitespace_wrapped {
827            stream.end_word();
828        }
829    }
830}
831
832/// Formats a [`InequalityExpr`](wdl_ast::v1::InequalityExpr).
833///
834/// # Panics
835///
836/// This will panic if the element does not have the expected children.
837pub fn format_inequality_expr(
838    element: &FormatElement,
839    stream: &mut TokenStream<PreToken>,
840    config: &Config,
841) {
842    for child in element.children().expect("inequality expr children") {
843        let whitespace_wrapped = child.element().kind() == SyntaxKind::NotEqual;
844        if whitespace_wrapped {
845            stream.end_word();
846        }
847        (&child).write(stream, config);
848        if whitespace_wrapped {
849            stream.end_word();
850        }
851    }
852}
853
854/// Formats a [`LessExpr`](wdl_ast::v1::LessExpr).
855///
856/// # Panics
857///
858/// This will panic if the element does not have the expected children.
859pub fn format_less_expr(
860    element: &FormatElement,
861    stream: &mut TokenStream<PreToken>,
862    config: &Config,
863) {
864    for child in element.children().expect("less expr children") {
865        let whitespace_wrapped = child.element().kind() == SyntaxKind::Less;
866        if whitespace_wrapped {
867            stream.end_word();
868        }
869        (&child).write(stream, config);
870        if whitespace_wrapped {
871            stream.end_word();
872        }
873    }
874}
875
876/// Formats a [`LessEqualExpr`](wdl_ast::v1::LessEqualExpr).
877///
878/// # Panics
879///
880/// This will panic if the element does not have the expected children.
881pub fn format_less_equal_expr(
882    element: &FormatElement,
883    stream: &mut TokenStream<PreToken>,
884    config: &Config,
885) {
886    for child in element.children().expect("less equal expr children") {
887        let whitespace_wrapped = child.element().kind() == SyntaxKind::LessEqual;
888        if whitespace_wrapped {
889            stream.end_word();
890        }
891        (&child).write(stream, config);
892        if whitespace_wrapped {
893            stream.end_word();
894        }
895    }
896}
897
898/// Formats a [`GreaterExpr`](wdl_ast::v1::GreaterExpr).
899///
900/// # Panics
901///
902/// This will panic if the element does not have the expected children.
903pub fn format_greater_expr(
904    element: &FormatElement,
905    stream: &mut TokenStream<PreToken>,
906    config: &Config,
907) {
908    for child in element.children().expect("greater expr children") {
909        let whitespace_wrapped = child.element().kind() == SyntaxKind::Greater;
910        if whitespace_wrapped {
911            stream.end_word();
912        }
913        (&child).write(stream, config);
914        if whitespace_wrapped {
915            stream.end_word();
916        }
917    }
918}
919
920/// Formats a [`GreaterEqualExpr`](wdl_ast::v1::GreaterEqualExpr).
921///
922/// # Panics
923///
924/// This will panic if the element does not have the expected children.
925pub fn format_greater_equal_expr(
926    element: &FormatElement,
927    stream: &mut TokenStream<PreToken>,
928    config: &Config,
929) {
930    for child in element.children().expect("greater equal expr children") {
931        let whitespace_wrapped = child.element().kind() == SyntaxKind::GreaterEqual;
932        if whitespace_wrapped {
933            stream.end_word();
934        }
935        (&child).write(stream, config);
936        if whitespace_wrapped {
937            stream.end_word();
938        }
939    }
940}
941
942/// Formats a [`ParenthesizedExpr`](wdl_ast::v1::ParenthesizedExpr).
943///
944/// # Panics
945///
946/// This will panic if the element does not have the expected children.
947pub fn format_parenthesized_expr(
948    element: &FormatElement,
949    stream: &mut TokenStream<PreToken>,
950    config: &Config,
951) {
952    for child in element.children().expect("parenthesized expr children") {
953        (&child).write(stream, config);
954    }
955}
956
957/// Formats an [`IfExpr`](wdl_ast::v1::IfExpr).
958///
959/// # Panics
960///
961/// This will panic if the element does not have the expected children.
962pub fn format_if_expr(
963    element: &FormatElement,
964    stream: &mut TokenStream<PreToken>,
965    config: &Config,
966) {
967    let in_chain = {
968        let mut cur = element.element().inner();
969        let mut result = false;
970        while let Some(prev) = cur.prev_sibling_or_token() {
971            cur = prev;
972            if cur.kind().is_trivia() {
973                continue;
974            }
975            result = cur.kind() == SyntaxKind::ElseKeyword;
976            break;
977        }
978        result
979    };
980
981    for child in element.children().expect("if expr children") {
982        match child.element().kind() {
983            SyntaxKind::ThenKeyword => {
984                if !in_chain {
985                    stream.increment_indent();
986                } else {
987                    stream.end_line();
988                }
989            }
990            SyntaxKind::ElseKeyword => {
991                stream.end_line();
992            }
993            _ => {}
994        }
995        (&child).write(stream, config);
996        stream.end_word();
997    }
998
999    if !in_chain {
1000        stream.decrement_indent();
1001    }
1002}