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
17fn 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 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
1640fn 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}