rune/fmt/
format.rs

1use core::mem::take;
2
3use crate::ast::{Delimiter, Kind};
4use crate::compile::Result;
5use crate::grammar::{classify, object_key, MaybeNode, NodeClass};
6
7use super::{Comments, Formatter, Node, Remaining, Stream, Tree};
8
9use Comments::*;
10use Kind::*;
11
12#[derive(Default)]
13struct Attrs {
14    skip: bool,
15}
16
17/// Test if a node is the `#[runefmt::skip]` attribute.
18fn is_runefmt_skip<'a>(fmt: &Formatter<'a>, node: Node<'a>) -> bool {
19    let mut skip = None;
20
21    _ = node.parse(|p| {
22        p.expect(K![#])?;
23
24        p.expect(K!['['])?;
25
26        p.expect(TokenStream)?.parse(|p| {
27            let ns = p.pump()?;
28            p.expect(K![::])?;
29            let name = p.pump()?;
30
31            skip = skip.or(
32                match (fmt.source.get(ns.span())?, fmt.source.get(name.span())?) {
33                    ("runefmt", "skip") => Some(true),
34                    _ => None,
35                },
36            );
37
38            Ok(())
39        })?;
40
41        p.expect(K![']'])?;
42        Ok(())
43    });
44
45    skip.unwrap_or(false)
46}
47
48pub(super) fn root<'a>(fmt: &mut Formatter<'a>, tree: &'a Tree) -> Result<()> {
49    tree.parse_all(|p| block_content(fmt, p))?;
50    fmt.nl(1)?;
51    Ok(())
52}
53
54fn expr_labels<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
55    while matches!(p.peek(), K!['label]) {
56        p.pump()?.fmt(fmt)?;
57        p.remaining(fmt, K![:])?.fmt(fmt)?;
58        fmt.ws()?;
59    }
60
61    Ok(())
62}
63
64fn inner_attributes<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
65    while let MaybeNode::Some(attr) = p.eat(InnerAttribute) {
66        attr.fmt(fmt)?;
67        fmt.nl(1)?;
68    }
69
70    Ok(())
71}
72
73fn attributes<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<Attrs> {
74    let mut attrs = Attrs::default();
75
76    while let MaybeNode::Some(attr) = p.eat(Attribute) {
77        attrs.skip |= is_runefmt_skip(fmt, attr.clone());
78        attr.fmt(fmt)?;
79        fmt.nl(1)?;
80    }
81
82    Ok(attrs)
83}
84
85fn modifiers<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
86    p.eat(Modifiers).parse(|p| {
87        let mut any = false;
88
89        for node in p.by_ref() {
90            match node.kind() {
91                ModifierSuper | ModifierSelf | ModifierCrate => {
92                    node.parse(|p| {
93                        p.expect(K!['('])?.fmt(fmt)?;
94                        fmt.comments(Infix)?;
95                        p.pump()?.fmt(fmt)?;
96                        fmt.comments(Infix)?;
97                        p.one(K![')']).fmt(fmt)?;
98                        Ok(())
99                    })?;
100                }
101                ModifierIn => {
102                    node.parse(|p| {
103                        p.expect(K!['('])?.fmt(fmt)?;
104                        p.expect(K![in])?.fmt(fmt)?;
105                        fmt.ws()?;
106                        p.expect(Path)?.parse(|p| path(fmt, p))?;
107                        p.one(K![')']).fmt(fmt)?;
108                        Ok(())
109                    })?;
110                }
111                Error => {
112                    return Err(p.expected("modifier"));
113                }
114                _ => {
115                    if any {
116                        fmt.ws()?;
117                    }
118
119                    node.fmt(fmt)?;
120                }
121            }
122
123            any = true;
124        }
125
126        if any {
127            fmt.ws()?;
128        }
129
130        Ok(())
131    })?;
132
133    Ok(())
134}
135
136fn item<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
137    let attrs = attributes(fmt, p)?;
138
139    p.pump()?.parse(|p| {
140        if attrs.skip {
141            p.write_remaining(fmt)?;
142            return Ok(());
143        }
144
145        match p.kind() {
146            ItemStruct => {
147                if attrs.skip {
148                    p.write_remaining(fmt)?;
149                } else {
150                    modifiers(fmt, p)?;
151                    item_struct(fmt, p)?;
152                }
153            }
154            ItemEnum => {
155                if attrs.skip {
156                    p.write_remaining(fmt)?;
157                } else {
158                    modifiers(fmt, p)?;
159                    item_enum(fmt, p)?;
160                }
161            }
162            ItemFn => {
163                if attrs.skip {
164                    p.write_remaining(fmt)?;
165                } else {
166                    modifiers(fmt, p)?;
167                    item_fn(fmt, p)?;
168                }
169            }
170            ItemUse => {
171                if attrs.skip {
172                    p.write_remaining(fmt)?;
173                } else {
174                    modifiers(fmt, p)?;
175                    item_use(fmt, p)?;
176                }
177            }
178            ItemImpl => {
179                if attrs.skip {
180                    p.write_remaining(fmt)?;
181                } else {
182                    modifiers(fmt, p)?;
183                    item_impl(fmt, p)?;
184                }
185            }
186            ItemMod | ItemFileMod => {
187                if attrs.skip {
188                    p.write_remaining(fmt)?;
189                } else {
190                    modifiers(fmt, p)?;
191                    item_mod(fmt, p)?;
192                }
193            }
194            ItemConst => {
195                modifiers(fmt, p)?;
196                item_const(fmt, p)?;
197            }
198            _ => return Err(p.expected(Item)),
199        }
200
201        Ok(())
202    })
203}
204
205fn stmt<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
206    match p.kind() {
207        Local => {
208            if attributes(fmt, p)?.skip {
209                p.write_remaining(fmt)?;
210            } else {
211                modifiers(fmt, p)?;
212                local(fmt, p)?;
213            }
214        }
215        Item => {
216            item(fmt, p)?;
217        }
218        _ => {
219            expr(fmt, p)?;
220        }
221    }
222
223    Ok(())
224}
225
226fn local<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
227    p.expect(K![let])?.fmt(fmt)?;
228    fmt.ws()?;
229    p.expect(Pat)?.parse(|p| pat(fmt, p))?;
230    fmt.ws()?;
231    p.one(K![=]).fmt(fmt)?;
232    fmt.ws()?;
233    p.expect(Expr)?.parse(|p| expr(fmt, p))?;
234    Ok(())
235}
236
237fn pat<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
238    let mut attrs = Attrs::default();
239
240    while let MaybeNode::Some(attr) = p.eat(Attribute) {
241        attrs.skip |= is_runefmt_skip(fmt, attr.clone());
242        attr.fmt(fmt)?;
243        fmt.ws()?;
244    }
245
246    p.pump()?.parse(|p| {
247        match p.kind() {
248            Lit => {
249                p.eat(K![-]).fmt(fmt)?;
250                p.pump()?.fmt(fmt)?;
251            }
252            PatIgnore => {
253                p.pump()?.fmt(fmt)?;
254            }
255            K![..] => {
256                p.pump()?.fmt(fmt)?;
257            }
258            Path => {
259                path(fmt, p)?;
260            }
261            PatArray => {
262                pat_array(fmt, p)?;
263            }
264            PatTuple => {
265                let trailing = p.eat(Path).parse(|p| path(fmt, p))?.is_none();
266                pat_tuple(fmt, p, trailing)?;
267            }
268            PatObject => {
269                pat_object(fmt, p)?;
270            }
271            _ => {
272                return Err(p.expected("pattern"));
273            }
274        }
275
276        Ok(())
277    })
278}
279
280fn path<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
281    for node in p.by_ref() {
282        match node.kind() {
283            PathGenerics => {
284                node.parse(|p| path_generics(fmt, p))?;
285            }
286            _ => {
287                node.fmt(fmt)?;
288            }
289        }
290    }
291
292    Ok(())
293}
294
295fn path_generics<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
296    p.expect(K![<])?.fmt(fmt)?;
297
298    let mut comma = Remaining::default();
299
300    while let MaybeNode::Some(node) = p.eat(Path) {
301        fmt.comments(Prefix)?;
302
303        if comma.fmt(fmt)? {
304            fmt.ws()?;
305        }
306
307        node.parse(|p| path(fmt, p))?;
308        comma = p.remaining(fmt, K![,])?;
309        fmt.comments(Suffix)?;
310    }
311
312    if !comma.ignore(fmt)? {
313        fmt.comments(Infix)?;
314    }
315
316    p.one(K![>]).fmt(fmt)?;
317    Ok(())
318}
319
320fn pat_array<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
321    p.expect(K!['['])?.fmt(fmt)?;
322
323    let mut comma = Remaining::default();
324
325    while let MaybeNode::Some(node) = p.eat_matching(|k| matches!(k, Pat | K![..])) {
326        fmt.comments(Prefix)?;
327
328        if comma.fmt(fmt)? {
329            fmt.ws()?;
330        }
331
332        match node.kind() {
333            K![..] => node.fmt(fmt)?,
334            _ => node.parse(|p| pat(fmt, p))?,
335        }
336
337        comma = p.remaining(fmt, K![,])?;
338        fmt.comments(Suffix)?;
339    }
340
341    if !comma.ignore(fmt)? {
342        fmt.comments(Infix)?;
343    }
344
345    p.one(K![']']).fmt(fmt)?;
346    Ok(())
347}
348
349fn pat_tuple<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>, trailing: bool) -> Result<()> {
350    p.expect(K!['('])?.fmt(fmt)?;
351
352    let mut count = 0usize;
353    let mut comma = Remaining::default();
354
355    while let MaybeNode::Some(node) = p.eat_matching(|k| matches!(k, Pat | K![..])) {
356        fmt.comments(Prefix)?;
357
358        if comma.fmt(fmt)? {
359            fmt.ws()?;
360        }
361
362        match node.kind() {
363            K![..] => node.fmt(fmt)?,
364            _ => node.parse(|p| pat(fmt, p))?,
365        };
366
367        comma = p.remaining(fmt, K![,])?;
368        count += 1;
369        fmt.comments(Suffix)?;
370    }
371
372    if count == 1 && trailing {
373        comma.fmt(fmt)?;
374    } else {
375        comma.ignore(fmt)?;
376
377        if count == 0 {
378            fmt.comments(Infix)?;
379        }
380    }
381
382    p.one(K![')']).fmt(fmt)?;
383    Ok(())
384}
385
386fn expr_tuple<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
387    p.expect(K!['('])?.fmt(fmt)?;
388
389    let mut count = 0usize;
390    let mut comma = Remaining::default();
391
392    while let MaybeNode::Some(node) = p.eat(Expr) {
393        fmt.comments(Prefix)?;
394
395        if comma.fmt(fmt)? {
396            fmt.ws()?;
397        }
398
399        node.parse(|p| expr_discard(fmt, p))?;
400        comma = p.remaining(fmt, K![,])?;
401        count += 1;
402        fmt.comments(Suffix)?;
403    }
404
405    if count == 1 {
406        comma.fmt(fmt)?;
407    } else {
408        comma.ignore(fmt)?;
409
410        if count == 0 {
411            fmt.comments(Infix)?;
412        }
413    }
414
415    p.one(K![')']).fmt(fmt)?;
416    Ok(())
417}
418
419fn expr_object<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
420    match p.peek() {
421        AnonymousObjectKey => {
422            p.expect(AnonymousObjectKey)?.fmt(fmt)?;
423        }
424        _ => {
425            p.expect(Path)?.parse(|p| path(fmt, p))?;
426            fmt.ws()?;
427        }
428    }
429
430    let mut count = 0;
431    let mut expanded = fmt.source.is_at_least(p.span(), 80)?;
432
433    for node in p.children() {
434        if expanded {
435            break;
436        }
437
438        count += usize::from(matches!(node.kind(), object_key!()));
439        expanded |= matches!(node.kind(), Kind::Comment) || count >= 6;
440    }
441
442    if expanded {
443        expr_object_loose(fmt, p)
444    } else {
445        expr_object_compact(fmt, p)
446    }
447}
448
449fn expr_object_loose<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
450    p.expect(K!['{'])?.fmt(fmt)?;
451
452    fmt.nl(1)?;
453    fmt.indent(1)?;
454
455    while matches!(p.peek(), object_key!()) {
456        fmt.comments(Line)?;
457        p.pump()?.fmt(fmt)?;
458
459        p.eat(K![:]).and_then(|colon| {
460            colon.fmt(fmt)?;
461            fmt.ws()?;
462            p.pump()?.parse(|p| expr(fmt, p))
463        })?;
464
465        p.remaining(fmt, K![,])?.fmt(fmt)?;
466        fmt.nl(1)?;
467    }
468
469    fmt.nl(1)?;
470    fmt.indent(-1)?;
471
472    p.remaining(fmt, K!['}'])?.fmt(fmt)?;
473    Ok(())
474}
475
476fn expr_object_compact<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
477    p.expect(K!['{'])?.fmt(fmt)?;
478
479    let mut comma = Remaining::default();
480
481    while matches!(p.peek(), object_key!()) {
482        comma.fmt(fmt)?;
483        fmt.ws()?;
484
485        p.pump()?.fmt(fmt)?;
486
487        p.eat(K![:]).and_then(|colon| {
488            colon.fmt(fmt)?;
489            fmt.ws()?;
490            p.pump()?.parse(|p| expr(fmt, p))
491        })?;
492
493        comma = p.remaining(fmt, K![,])?;
494    }
495
496    if comma.ignore(fmt)? {
497        fmt.ws()?;
498    } else {
499        fmt.comments(Infix)?;
500    }
501
502    p.remaining(fmt, K!['}'])?.fmt(fmt)?;
503    Ok(())
504}
505
506fn pat_object<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
507    match p.peek() {
508        AnonymousObjectKey => {
509            p.expect(AnonymousObjectKey)?.fmt(fmt)?;
510        }
511        _ => {
512            p.expect(Path)?.parse(|p| path(fmt, p))?;
513            fmt.ws()?;
514        }
515    }
516
517    p.expect(K!['{'])?.fmt(fmt)?;
518
519    let mut comma = Remaining::default();
520
521    while matches!(p.peek(), object_key!() | K![..]) {
522        comma.fmt(fmt)?;
523        fmt.ws()?;
524
525        match p.peek() {
526            object_key!() => {
527                p.pump()?.fmt(fmt)?;
528
529                p.eat(K![:]).and_then(|colon| {
530                    colon.fmt(fmt)?;
531                    fmt.ws()?;
532                    p.expect(Pat)?.parse(|p| pat(fmt, p))
533                })?;
534            }
535            _ => {
536                p.expect(K![..])?.fmt(fmt)?;
537            }
538        }
539
540        comma = p.remaining(fmt, K![,])?;
541    }
542
543    if comma.ignore(fmt)? {
544        fmt.ws()?;
545    } else {
546        fmt.comments(Infix)?;
547    }
548
549    p.remaining(fmt, K!['}'])?.fmt(fmt)?;
550    Ok(())
551}
552
553fn expr_discard<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
554    expr(fmt, p)?;
555    Ok(())
556}
557
558fn expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<Kind> {
559    let mut attrs = Attrs::default();
560
561    while let MaybeNode::Some(attr) = p.eat(Attribute) {
562        attrs.skip |= is_runefmt_skip(fmt, attr.clone());
563        attr.fmt(fmt)?;
564        fmt.ws()?;
565    }
566
567    if attrs.skip {
568        p.write_remaining(fmt)?;
569        Ok(Expr)
570    } else {
571        modifiers(fmt, p)?;
572        expr_labels(fmt, p)?;
573        p.pump()?.parse(|p| inner_expr(fmt, p))
574    }
575}
576
577fn inner_expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<Kind> {
578    match p.kind() {
579        Path => {
580            path(fmt, p)?;
581        }
582        Lit => {
583            p.eat(K![-]).fmt(fmt)?;
584            p.pump()?.fmt(fmt)?;
585        }
586        TemplateString => {
587            p.pump()?.fmt(fmt)?;
588        }
589        Block => {
590            block_with(fmt, p, true)?;
591        }
592        ExprAssign => {
593            expr_assign(fmt, p)?;
594        }
595        ExprArray => {
596            exprs(fmt, p, K!['['], K![']'])?;
597        }
598        ExprTuple => {
599            expr_tuple(fmt, p)?;
600        }
601        ExprObject => {
602            expr_object(fmt, p)?;
603        }
604        ExprBinary => {
605            expr_binary(fmt, p)?;
606        }
607        ExprUnary => {
608            expr_unary(fmt, p)?;
609        }
610        ExprGroup => {
611            expr_group(fmt, p)?;
612        }
613        ExprEmptyGroup => {
614            expr_empty_group(fmt, p)?;
615        }
616        ExprIf => {
617            expr_if(fmt, p)?;
618        }
619        ExprWhile => {
620            expr_while(fmt, p)?;
621        }
622        ExprLoop => {
623            expr_loop(fmt, p)?;
624        }
625        ExprBreak => {
626            expr_break(fmt, p)?;
627        }
628        ExprContinue => {
629            expr_continue(fmt, p)?;
630        }
631        ExprReturn => {
632            expr_return(fmt, p)?;
633        }
634        ExprYield => {
635            expr_yield(fmt, p)?;
636        }
637        ExprFor => {
638            expr_for(fmt, p)?;
639        }
640        ExprMatch => {
641            expr_match(fmt, p)?;
642        }
643        ExprSelect => {
644            expr_select(fmt, p)?;
645        }
646        ExprRangeFull => {
647            p.pump()?.fmt(fmt)?;
648        }
649        ExprRangeFrom => {
650            p.pump()?.parse(|p| inner_expr(fmt, p))?;
651            p.pump()?.fmt(fmt)?;
652        }
653        ExprRangeTo | ExprRangeToInclusive => {
654            p.pump()?.fmt(fmt)?;
655            p.pump()?.parse(|p| inner_expr(fmt, p))?;
656        }
657        ExprRange | ExprRangeInclusive => {
658            p.pump()?.parse(|p| inner_expr(fmt, p))?;
659            p.pump()?.fmt(fmt)?;
660            p.pump()?.parse(|p| inner_expr(fmt, p))?;
661        }
662        ExprClosure => {
663            expr_closure(fmt, p)?;
664        }
665        ExprChain => {
666            expr_chain(fmt, p)?;
667        }
668        ExprMacroCall => {
669            p.expect(Path)?.parse(|p| path(fmt, p))?;
670            p.expect(K![!])?.fmt(fmt)?;
671
672            match p.peek() {
673                K!['{'] => loose_expr_macro_call(fmt, p)?,
674                _ => compact_expr_macro_call(fmt, p)?,
675            }
676        }
677        Error => {
678            if fmt.options.error_recovery {
679                p.fmt_remaining_trimmed(fmt)?;
680            } else {
681                return Err(p.expected("inner expression"));
682            }
683        }
684        _ => {
685            return Err(p.expected("inner expression"));
686        }
687    }
688
689    Ok(p.kind())
690}
691
692fn loose_expr_macro_call<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
693    p.expect(K!['{'])?.fmt(fmt)?;
694
695    p.expect(TokenStream)?.parse(|p| {
696        if p.is_eof() {
697            return Ok(());
698        }
699
700        fmt.nl(1)?;
701        fmt.indent(1)?;
702
703        let mut buf = None;
704        let mut has_ws = false;
705
706        while let Some(node) = p.next_with_ws() {
707            if matches!(node.kind(), K![,]) {
708                fmt.write_raw(node)?;
709                fmt.nl(1)?;
710                has_ws = true;
711                continue;
712            }
713
714            if node.is_whitespace() {
715                buf = Some(node);
716                continue;
717            }
718
719            if let Some(buf) = buf.take() {
720                if !has_ws {
721                    fmt.write_raw(buf)?;
722                }
723            }
724
725            fmt.flush_whitespace(false)?;
726            fmt.write_raw(node)?;
727            has_ws = false;
728        }
729
730        fmt.nl(1)?;
731        fmt.indent(-1)?;
732        Ok(())
733    })?;
734
735    p.expect(K!['}'])?.fmt(fmt)?;
736    Ok(())
737}
738
739fn compact_expr_macro_call<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
740    p.expect(K!['('])?.fmt(fmt)?;
741
742    p.expect(TokenStream)?.parse(|p| {
743        let mut buf = None;
744        let mut has_ws = false;
745
746        while let Some(node) = p.next_with_ws() {
747            if matches!(node.kind(), K![,]) {
748                fmt.write_raw(node)?;
749                fmt.ws()?;
750                has_ws = true;
751                continue;
752            }
753
754            if node.is_whitespace() {
755                buf = Some(node);
756                continue;
757            }
758
759            if let Some(buf) = buf.take() {
760                if !has_ws {
761                    fmt.write_raw(buf)?;
762                }
763            }
764
765            fmt.flush_whitespace(false)?;
766            fmt.write_raw(node)?;
767            has_ws = false;
768        }
769
770        Ok(())
771    })?;
772
773    p.expect(K![')'])?.fmt(fmt)?;
774    Ok(())
775}
776
777fn expr_assign<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
778    p.expect(Expr)?.parse(|p| expr(fmt, p))?;
779    fmt.ws()?;
780    p.expect(K![=])?.fmt(fmt)?;
781    fmt.ws()?;
782    p.expect(Expr)?.parse(|p| expr(fmt, p))?;
783    Ok(())
784}
785
786fn exprs<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>, open: Kind, close: Kind) -> Result<()> {
787    let mut count = 0;
788    let mut expanded = fmt.source.is_at_least(p.span(), 80)?;
789
790    for node in p.children() {
791        if expanded {
792            break;
793        }
794
795        count += usize::from(matches!(node.kind(), Expr));
796        expanded |= matches!(node.kind(), Kind::Comment) || count >= 6;
797    }
798
799    p.one(open).fmt(fmt)?;
800
801    if expanded {
802        exprs_loose(fmt, p)?;
803    } else {
804        exprs_compact(fmt, p)?;
805    }
806
807    p.one(close).fmt(fmt)?;
808    Ok(())
809}
810
811fn exprs_loose<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
812    fmt.nl(1)?;
813    fmt.indent(1)?;
814
815    while let MaybeNode::Some(node) = p.eat(Expr) {
816        fmt.comments(Line)?;
817        node.parse(|p| expr(fmt, p))?;
818        p.remaining(fmt, K![,])?.fmt(fmt)?;
819        fmt.nl(1)?;
820    }
821
822    fmt.nl(1)?;
823    fmt.comments(Line)?;
824    fmt.indent(-1)?;
825    Ok(())
826}
827
828fn exprs_compact<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
829    let mut comma = Remaining::default();
830
831    while let MaybeNode::Some(node) = p.eat(Expr) {
832        fmt.comments(Prefix)?;
833
834        if comma.fmt(fmt)? {
835            fmt.ws()?;
836        }
837
838        node.parse(|p| expr(fmt, p))?;
839        comma = p.remaining(fmt, K![,])?;
840        fmt.comments(Suffix)?;
841    }
842
843    if !comma.ignore(fmt)? {
844        fmt.comments(Infix)?;
845    }
846
847    Ok(())
848}
849
850fn expr_binary<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
851    p.pump()?.parse(|p| inner_expr(fmt, p))?;
852
853    while let MaybeNode::Some(op) = p.eat(ExprOperator) {
854        fmt.ws()?;
855        op.fmt(fmt)?;
856        fmt.ws()?;
857        p.pump()?.parse(|p| inner_expr(fmt, p))?;
858    }
859
860    Ok(())
861}
862
863fn expr_unary<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
864    p.pump()?.fmt(fmt)?;
865    p.pump()?.parse(|p| inner_expr(fmt, p))?;
866    Ok(())
867}
868
869fn expr_group<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
870    p.expect(K!['('])?.fmt(fmt)?;
871
872    let mut empty = true;
873
874    p.eat(Expr).parse(|p| {
875        fmt.comments(Prefix)?;
876        expr(fmt, p)?;
877        fmt.comments(Suffix)?;
878        empty = false;
879        Ok(())
880    })?;
881
882    if empty {
883        fmt.comments(Infix)?;
884    }
885
886    p.one(K![')']).fmt(fmt)?;
887    Ok(())
888}
889
890fn expr_empty_group<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
891    p.expect(Kind::Open(Delimiter::Empty))?.ignore(fmt)?;
892
893    let mut empty = true;
894
895    p.eat(Expr).parse(|p| {
896        fmt.comments(Prefix)?;
897        expr(fmt, p)?;
898        fmt.comments(Suffix)?;
899        empty = false;
900        Ok(())
901    })?;
902
903    if empty {
904        fmt.comments(Infix)?;
905    }
906
907    p.one(Kind::Open(Delimiter::Empty)).ignore(fmt)?;
908    Ok(())
909}
910
911fn expr_if<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
912    p.expect(If)?.fmt(fmt)?;
913    fmt.ws()?;
914    condition_or_expr(fmt, p)?;
915    fmt.ws()?;
916
917    if p.eat(Block).parse(|p| block(fmt, p))?.is_none() {
918        fmt.lit("{}")?;
919    }
920
921    for node in p.by_ref() {
922        match node.kind() {
923            ExprElse => {
924                node.parse(|p| {
925                    fmt.ws()?;
926                    p.expect(K![else])?.fmt(fmt)?;
927                    fmt.ws()?;
928                    p.expect(Block)?.parse(|p| block(fmt, p))?;
929                    Ok(())
930                })?;
931            }
932            ExprElseIf => {
933                node.parse(|p| {
934                    fmt.ws()?;
935                    p.expect(K![else])?.fmt(fmt)?;
936                    fmt.ws()?;
937                    p.expect(K![if])?.fmt(fmt)?;
938                    fmt.ws()?;
939                    condition_or_expr(fmt, p)?;
940                    fmt.ws()?;
941                    p.expect(Block)?.parse(|p| block(fmt, p))?;
942                    Ok(())
943                })?;
944            }
945            _ => {
946                node.fmt(fmt)?;
947            }
948        }
949    }
950
951    Ok(())
952}
953
954fn expr_while<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
955    p.expect(K![while])?.fmt(fmt)?;
956    fmt.ws()?;
957    condition_or_expr(fmt, p)?;
958    fmt.ws()?;
959    p.expect(Block)?.parse(|p| block(fmt, p))?;
960    Ok(())
961}
962
963fn expr_loop<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
964    p.expect(K![loop])?.fmt(fmt)?;
965    fmt.ws()?;
966    p.expect(Block)?.parse(|p| block(fmt, p))?;
967    Ok(())
968}
969
970fn expr_for<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
971    p.expect(K![for])?.fmt(fmt)?;
972    fmt.ws()?;
973    p.expect(Pat)?.parse(|p| pat(fmt, p))?;
974    fmt.ws()?;
975    p.expect(K![in])?.fmt(fmt)?;
976    fmt.ws()?;
977    p.pump()?.parse(|p| expr(fmt, p))?;
978    fmt.ws()?;
979    p.expect(Block)?.parse(|p| block(fmt, p))?;
980    Ok(())
981}
982
983fn expr_break<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
984    p.expect(K![break])?.fmt(fmt)?;
985
986    while matches!(p.peek(), K!['label]) {
987        fmt.ws()?;
988        p.pump()?.fmt(fmt)?;
989    }
990
991    p.eat(Expr).parse(|p| {
992        fmt.ws()?;
993        expr(fmt, p)
994    })?;
995
996    Ok(())
997}
998
999fn expr_continue<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1000    p.expect(K![continue])?.fmt(fmt)?;
1001
1002    while matches!(p.peek(), K!['label]) {
1003        fmt.ws()?;
1004        p.pump()?.fmt(fmt)?;
1005    }
1006
1007    Ok(())
1008}
1009
1010fn expr_return<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1011    p.expect(K![return])?.fmt(fmt)?;
1012
1013    p.eat(Expr).parse(|p| {
1014        fmt.ws()?;
1015        expr(fmt, p)
1016    })?;
1017
1018    Ok(())
1019}
1020
1021fn expr_yield<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1022    p.expect(K![yield])?.fmt(fmt)?;
1023
1024    p.eat(Expr).parse(|p| {
1025        fmt.ws()?;
1026        expr(fmt, p)
1027    })?;
1028
1029    Ok(())
1030}
1031
1032fn expr_select<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1033    p.expect(K![select])?.fmt(fmt)?;
1034    fmt.ws()?;
1035
1036    let MaybeNode::Some(open) = p.eat(K!['{']) else {
1037        fmt.lit("{}")?;
1038        return Ok(());
1039    };
1040
1041    fmt.indent(1)?;
1042    open.fmt(fmt)?;
1043
1044    while let MaybeNode::Some(node) = p.eat(ExprSelectArm) {
1045        fmt.nl(1)?;
1046        fmt.comments(Line)?;
1047
1048        let is_block = node.parse(|p| {
1049            match p.peek() {
1050                K![default] => {
1051                    p.expect(K![default])?.fmt(fmt)?;
1052                }
1053                _ => {
1054                    p.expect(Pat)?.parse(|p| pat(fmt, p))?;
1055                }
1056            }
1057
1058            p.eat(K![=]).and_then(|eq| {
1059                fmt.ws()?;
1060                eq.fmt(fmt)?;
1061                fmt.ws()?;
1062                p.pump()?.parse(|p| expr(fmt, p))
1063            })?;
1064
1065            fmt.ws()?;
1066            p.one(K![=>]).fmt(fmt)?;
1067            fmt.ws()?;
1068
1069            p.pump()?.parse(|p| {
1070                let kind = expr(fmt, p)?;
1071                Ok(matches!(kind, Block))
1072            })
1073        })?;
1074
1075        p.remaining(fmt, K![,])?.write_only_if(fmt, !is_block)?;
1076    }
1077
1078    fmt.comments(Line)?;
1079    fmt.nl(1)?;
1080    fmt.indent(-1)?;
1081    p.one(K!['}']).fmt(fmt)?;
1082    Ok(())
1083}
1084
1085fn expr_match<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1086    p.expect(K![match])?.fmt(fmt)?;
1087    fmt.ws()?;
1088    p.pump()?.parse(|p| expr(fmt, p))?;
1089    fmt.ws()?;
1090
1091    p.one(K!['{']).fmt(fmt)?;
1092
1093    let mut any = false;
1094
1095    while let MaybeNode::Some(node) = p.eat(ExprMatchArm) {
1096        if !any {
1097            fmt.indent(1)?;
1098        }
1099
1100        any = true;
1101
1102        let is_block = node.parse(|p| {
1103            fmt.nl(1)?;
1104            fmt.comments(Line)?;
1105
1106            p.expect(Pat)?.parse(|p| pat(fmt, p))?;
1107
1108            p.eat(K![if]).and_then(|node| {
1109                fmt.ws()?;
1110                node.fmt(fmt)?;
1111                fmt.ws()?;
1112                p.expect(Expr)?.parse(|p| expr(fmt, p))
1113            })?;
1114
1115            fmt.ws()?;
1116            p.one(K![=>]).fmt(fmt)?;
1117            fmt.ws()?;
1118
1119            p.pump()?.parse(|p| {
1120                let kind = expr(fmt, p)?;
1121                Ok(matches!(kind, Block))
1122            })
1123        })?;
1124
1125        p.remaining(fmt, K![,])?.write_only_if(fmt, !is_block)?;
1126    }
1127
1128    if any {
1129        fmt.comments(Line)?;
1130        fmt.nl(1)?;
1131        fmt.indent(-1)?;
1132    } else {
1133        fmt.comments(Infix)?;
1134    }
1135
1136    p.one(K!['}']).fmt(fmt)?;
1137    Ok(())
1138}
1139
1140fn expr_closure<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1141    if let MaybeNode::Some(node) = p.eat(ClosureArguments) {
1142        node.parse(|p| {
1143            if let MaybeNode::Some(open) = p.eat(K![||]) {
1144                open.fmt(fmt)?;
1145                return Ok(());
1146            }
1147
1148            p.expect(K![|])?.fmt(fmt)?;
1149
1150            let mut comma = Remaining::default();
1151
1152            while let MaybeNode::Some(node) = p.eat(Pat) {
1153                fmt.comments(Prefix)?;
1154
1155                if comma.fmt(fmt)? {
1156                    fmt.ws()?;
1157                }
1158
1159                node.parse(|p| pat(fmt, p))?;
1160                comma = p.remaining(fmt, K![,])?;
1161                fmt.comments(Suffix)?;
1162            }
1163
1164            if !comma.ignore(fmt)? {
1165                fmt.comments(Infix)?;
1166            }
1167
1168            p.one(K![|]).fmt(fmt)?;
1169            Ok(())
1170        })?;
1171    } else {
1172        fmt.lit("||")?;
1173    }
1174
1175    fmt.ws()?;
1176
1177    if p.eat(Expr).parse(|p| expr(fmt, p))?.is_none() {
1178        fmt.lit("{}")?;
1179    }
1180
1181    Ok(())
1182}
1183
1184fn expr_chain<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1185    let expanded = fmt.source.is_at_least(p.span(), 80)?;
1186
1187    // If the first expression *is* small, and there are no other expressions
1188    // that need indentation in the chain, we can keep it all on one line.
1189    let head = p.pump()?.parse(|p| {
1190        let first = p.span();
1191        inner_expr(fmt, p)?;
1192        Ok(first)
1193    })?;
1194
1195    let tail = 'tail: {
1196        for (n, node) in p.children().enumerate() {
1197            if matches!(node.kind(), ExprCall) {
1198                break 'tail Some((n, node.span()));
1199            }
1200        }
1201
1202        None
1203    };
1204
1205    let first_is_small = if let Some((_, tail)) = tail {
1206        !fmt.source.is_at_least(head.join(tail.head()), 80)?
1207    } else {
1208        !fmt.source.is_at_least(head, 80)?
1209    };
1210
1211    let from;
1212
1213    if expanded && first_is_small {
1214        let mut found = false;
1215        let first = tail.map(|(n, _)| n).unwrap_or_default();
1216
1217        for node in p.children().skip(first.wrapping_add(1)) {
1218            found |= matches!(node.kind(), ExprField | ExprAwait);
1219
1220            if found {
1221                break;
1222            }
1223        }
1224
1225        if found {
1226            from = 0;
1227        } else {
1228            from = first + 1;
1229        }
1230    } else {
1231        from = if expanded { 0 } else { usize::MAX };
1232    }
1233
1234    let mut unindented = true;
1235
1236    for (n, node) in p.by_ref().enumerate() {
1237        if n >= from {
1238            fmt.indent(isize::from(take(&mut unindented)))?;
1239            fmt.nl(usize::from(matches!(node.kind(), ExprField | ExprAwait)))?;
1240        }
1241
1242        node.parse(|p| {
1243            match p.kind() {
1244                ExprTry => {
1245                    p.one(K![?]).fmt(fmt)?;
1246                }
1247                ExprAwait => {
1248                    p.one(K![.]).fmt(fmt)?;
1249                    p.one(K![await]).fmt(fmt)?;
1250                }
1251                ExprField => {
1252                    p.one(K![.]).fmt(fmt)?;
1253
1254                    match p.peek() {
1255                        K![number] => {
1256                            p.pump()?.fmt(fmt)?;
1257                        }
1258                        _ => {
1259                            p.expect(Path)?.parse(|p| path(fmt, p))?;
1260                        }
1261                    }
1262                }
1263                ExprCall => {
1264                    exprs(fmt, p, K!['('], K![')'])?;
1265                }
1266                ExprIndex => {
1267                    p.expect(K!['['])?.fmt(fmt)?;
1268                    fmt.comments(Prefix)?;
1269                    p.pump()?.parse(|p| expr(fmt, p))?;
1270                    fmt.comments(Suffix)?;
1271                    p.one(K![']']).fmt(fmt)?;
1272                }
1273                _ => {
1274                    return Err(p.expected(ExprChain));
1275                }
1276            }
1277
1278            Ok(())
1279        })?;
1280    }
1281
1282    if !unindented {
1283        fmt.indent(-1)?;
1284    }
1285
1286    Ok(())
1287}
1288
1289fn condition_or_expr<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1290    if p.eat(Condition).parse(|p| condition(fmt, p))?.is_none() {
1291        p.expect(Expr)?.parse(|p| expr(fmt, p))?;
1292    }
1293
1294    Ok(())
1295}
1296
1297fn condition<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1298    p.expect(K![let])?.fmt(fmt)?;
1299    fmt.ws()?;
1300    p.expect(Pat)?.parse(|p| pat(fmt, p))?;
1301    fmt.ws()?;
1302    p.expect(K![=])?.fmt(fmt)?;
1303    fmt.ws()?;
1304    p.expect(Expr)?.parse(|p| expr(fmt, p))?;
1305    Ok(())
1306}
1307
1308fn item_struct<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1309    p.expect(K![struct])?.fmt(fmt)?;
1310
1311    if matches!(p.peek(), K![ident]) {
1312        fmt.ws()?;
1313        p.pump()?.fmt(fmt)?;
1314    }
1315
1316    let body = p.pump()?;
1317
1318    match body.kind() {
1319        StructBody => {
1320            fmt.ws()?;
1321            body.parse(|p| struct_body(fmt, p))?;
1322        }
1323        TupleBody => {
1324            body.parse(|p| tuple_body(fmt, p))?;
1325        }
1326        EmptyBody => {}
1327        _ => {
1328            return Err(body.unsupported("struct declaration"));
1329        }
1330    };
1331
1332    Ok(())
1333}
1334
1335fn item_enum<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1336    p.expect(K![enum])?.fmt(fmt)?;
1337
1338    if matches!(p.peek(), K![ident]) {
1339        fmt.ws()?;
1340        p.pump()?.fmt(fmt)?;
1341    }
1342
1343    fmt.ws()?;
1344
1345    let MaybeNode::Some(node) = p.eat(K!['{']) else {
1346        fmt.lit("{}")?;
1347        return Ok(());
1348    };
1349
1350    node.fmt(fmt)?;
1351    fmt.indent(1)?;
1352
1353    let mut empty = true;
1354
1355    while let MaybeNode::Some(node) = p.eat(Variant) {
1356        fmt.nl(1)?;
1357        fmt.comments(Line)?;
1358        node.parse(|p| variant(fmt, p))?;
1359        empty = false;
1360        p.remaining(fmt, K![,])?.fmt(fmt)?;
1361    }
1362
1363    fmt.comments(Line)?;
1364    fmt.nl(usize::from(!empty))?;
1365    fmt.indent(-1)?;
1366    p.one(K!['}']).fmt(fmt)?;
1367    Ok(())
1368}
1369
1370fn variant<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1371    fmt.comments(Line)?;
1372
1373    if matches!(p.peek(), K![ident]) {
1374        p.pump()?.fmt(fmt)?;
1375    }
1376
1377    let body = p.pump()?;
1378
1379    match body.kind() {
1380        StructBody => {
1381            fmt.ws()?;
1382            body.parse(|p| struct_body(fmt, p))?;
1383        }
1384        TupleBody => {
1385            body.parse(|p| tuple_body(fmt, p))?;
1386        }
1387        EmptyBody => {}
1388        _ => {
1389            return Err(body.unsupported("variant body"));
1390        }
1391    }
1392
1393    Ok(())
1394}
1395
1396fn struct_body<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1397    p.expect(K!['{'])?.fmt(fmt)?;
1398    fmt.indent(1)?;
1399    fmt.comments(Line)?;
1400
1401    let mut empty = true;
1402
1403    while let MaybeNode::Some(field) = p.eat(Field) {
1404        fmt.nl(1)?;
1405        fmt.comments(Line)?;
1406        field.parse(|p| p.pump()?.fmt(fmt))?;
1407        p.remaining(fmt, K![,])?.fmt(fmt)?;
1408        empty = false;
1409    }
1410
1411    fmt.comments(Line)?;
1412    fmt.nl(usize::from(!empty))?;
1413    fmt.indent(-1)?;
1414    p.one(K!['}']).fmt(fmt)?;
1415    Ok(())
1416}
1417
1418fn tuple_body<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1419    p.expect(K!['('])?.fmt(fmt)?;
1420
1421    let mut comma = Remaining::default();
1422
1423    while let MaybeNode::Some(node) = p.eat(Field) {
1424        fmt.comments(Prefix)?;
1425
1426        if comma.fmt(fmt)? {
1427            fmt.ws()?;
1428        }
1429
1430        node.parse(|p| p.pump()?.fmt(fmt))?;
1431        comma = p.remaining(fmt, K![,])?;
1432        fmt.comments(Suffix)?;
1433    }
1434
1435    if !comma.ignore(fmt)? {
1436        fmt.comments(Infix)?;
1437    }
1438
1439    p.one(K![')']).fmt(fmt)?;
1440    fmt.comments(Suffix)?;
1441    Ok(())
1442}
1443
1444fn item_fn<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1445    p.expect(K![fn])?.fmt(fmt)?;
1446
1447    if matches!(p.peek(), K![ident]) {
1448        fmt.ws()?;
1449        p.pump()?.fmt(fmt)?;
1450    }
1451
1452    if p.eat(FnArgs).parse(|p| fn_args(fmt, p))?.is_none() {
1453        fmt.lit("()")?;
1454    }
1455
1456    fmt.ws()?;
1457
1458    if p.eat(Block).parse(|p| block(fmt, p))?.is_none() {
1459        fmt.lit("{")?;
1460        fmt.nl(1)?;
1461        fmt.lit("}")?;
1462    }
1463
1464    Ok(())
1465}
1466
1467fn item_use<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1468    p.expect(K![use])?.fmt(fmt)?;
1469    fmt.ws()?;
1470    item_use_path(fmt, p)
1471}
1472
1473fn item_use_path<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1474    while let Some(node) = p.next() {
1475        match node.kind() {
1476            ItemUseGroup => {
1477                node.parse(|p: &mut Stream<'a>| item_use_group(fmt, p))?;
1478            }
1479            K![as] => {
1480                fmt.ws()?;
1481                node.fmt(fmt)?;
1482
1483                if let MaybeNode::Some(node) = p.eat_matching(|k| matches!(k, K![ident])) {
1484                    fmt.ws()?;
1485                    node.fmt(fmt)?;
1486                }
1487
1488                break;
1489            }
1490            _ => {
1491                node.fmt(fmt)?;
1492            }
1493        }
1494    }
1495
1496    Ok(())
1497}
1498
1499fn item_use_group<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1500    let mut nested = 0;
1501
1502    for n in p.children() {
1503        nested += usize::from(matches!(n.kind(), ItemUsePath));
1504
1505        if nested > 1 {
1506            break;
1507        }
1508    }
1509
1510    let open = p.expect(K!['{'])?;
1511
1512    if nested == 1 {
1513        fmt.ignore(open)?;
1514    } else {
1515        open.fmt(fmt)?;
1516    }
1517
1518    let mut comma = Remaining::default();
1519
1520    while let MaybeNode::Some(inner) = p.eat(ItemUsePath) {
1521        fmt.comments(Prefix)?;
1522
1523        if comma.fmt(fmt)? {
1524            fmt.ws()?;
1525        }
1526
1527        inner.parse(|p| item_use_path(fmt, p))?;
1528        comma = p.remaining(fmt, K![,])?;
1529        fmt.comments(Suffix)?;
1530    }
1531
1532    if !comma.ignore(fmt)? {
1533        fmt.comments(Infix)?;
1534    }
1535
1536    let close = p.one(K!['}']);
1537
1538    if nested == 1 {
1539        close.ignore(fmt)?;
1540    } else {
1541        close.fmt(fmt)?;
1542    }
1543
1544    Ok(())
1545}
1546
1547fn item_impl<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1548    p.expect(K![impl])?.fmt(fmt)?;
1549    fmt.ws()?;
1550    p.expect(Path)?.parse(|p| path(fmt, p))?;
1551    fmt.ws()?;
1552    p.expect(Block)?.parse(|p| block(fmt, p))?;
1553    Ok(())
1554}
1555
1556fn item_mod<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1557    p.expect(K![mod])?.fmt(fmt)?;
1558    fmt.ws()?;
1559    p.pump()?.fmt(fmt)?;
1560
1561    p.eat(Block).parse(|p| {
1562        fmt.ws()?;
1563        block(fmt, p)
1564    })?;
1565
1566    Ok(())
1567}
1568
1569fn item_const<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1570    p.pump()?.fmt(fmt)?;
1571    fmt.ws()?;
1572    p.one(K![=]).fmt(fmt)?;
1573    fmt.ws()?;
1574    p.pump()?.parse(|p| expr(fmt, p))?;
1575    Ok(())
1576}
1577
1578fn fn_args<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1579    p.expect(K!['('])?.fmt(fmt)?;
1580    p.remaining(fmt, K![,])?.ignore(fmt)?;
1581
1582    let mut comma = Remaining::default();
1583
1584    while let MaybeNode::Some(node) = p.eat(Pat) {
1585        fmt.comments(Prefix)?;
1586
1587        if comma.fmt(fmt)? {
1588            fmt.ws()?;
1589        }
1590
1591        node.parse(|p| pat(fmt, p))?;
1592        comma = p.remaining(fmt, K![,])?;
1593        fmt.comments(Suffix)?;
1594    }
1595
1596    if !comma.ignore(fmt)? {
1597        fmt.comments(Infix)?;
1598    }
1599
1600    p.one(K![')']).fmt(fmt)?;
1601    Ok(())
1602}
1603
1604fn block<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1605    block_with(fmt, p, false)
1606}
1607
1608fn block_with<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>, compact: bool) -> Result<()> {
1609    p.one(K!['{']).fmt(fmt)?;
1610
1611    p.expect(BlockBody)?.parse(|p| {
1612        let expanded = !p.is_eof() || !compact;
1613
1614        if expanded {
1615            fmt.indent(1)?;
1616            fmt.nl(1)?;
1617            fmt.comments(Line)?;
1618        } else {
1619            fmt.comments(Prefix)?;
1620        }
1621
1622        block_content(fmt, p)?;
1623
1624        if expanded {
1625            fmt.nl(1)?;
1626            fmt.comments(Line)?;
1627            fmt.nl(1)?;
1628            fmt.indent(-1)?;
1629        } else {
1630            fmt.comments(Suffix)?;
1631        }
1632
1633        Ok(())
1634    })?;
1635
1636    p.one(K!['}']).fmt(fmt)?;
1637    Ok(())
1638}
1639
1640/// The contents of a block.
1641fn block_content<'a>(fmt: &mut Formatter<'a>, p: &mut Stream<'a>) -> Result<()> {
1642    inner_attributes(fmt, p)?;
1643
1644    let mut last_kind = None;
1645
1646    while !p.is_eof() {
1647        let node = p.pump()?;
1648        let (needs_semi, class) = classify(&node);
1649
1650        if let Some(last_kind) = last_kind {
1651            let n = match last_kind {
1652                NodeClass::Item => 1,
1653                NodeClass::Const => usize::from(!matches!(class, NodeClass::Const)),
1654                NodeClass::Local => usize::from(!matches!(class, NodeClass::Local)),
1655                _ => 0,
1656            };
1657
1658            fmt.nl(n + 1)?;
1659        }
1660
1661        fmt.comments(Line)?;
1662
1663        node.parse(|p| stmt(fmt, p))?;
1664
1665        let trailing_semi = p.remaining(fmt, K![;])?;
1666
1667        if needs_semi || trailing_semi.is_present() {
1668            fmt.comments(Suffix)?;
1669        }
1670
1671        trailing_semi.write_if(fmt, needs_semi)?;
1672        last_kind = Some(class);
1673    }
1674
1675    Ok(())
1676}