cl_ast/ast_impl/
display.rs

1//! Implements [Display] for [AST](super::super) Types
2
3use super::*;
4use format::{delimiters::*, *};
5use std::{
6    borrow::Borrow,
7    fmt::{Display, Write},
8};
9
10fn separate<I: Display, W: Write>(
11    iterable: impl IntoIterator<Item = I>,
12    sep: &'static str,
13) -> impl FnOnce(W) -> std::fmt::Result {
14    move |mut f| {
15        for (idx, item) in iterable.into_iter().enumerate() {
16            if idx > 0 {
17                f.write_str(sep)?;
18            }
19            write!(f, "{item}")?;
20        }
21        Ok(())
22    }
23}
24
25impl Display for Mutability {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            Mutability::Not => Ok(()),
29            Mutability::Mut => "mut ".fmt(f),
30        }
31    }
32}
33
34impl Display for Visibility {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        match self {
37            Visibility::Private => Ok(()),
38            Visibility::Public => "pub ".fmt(f),
39        }
40    }
41}
42
43impl Display for Literal {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Literal::Bool(v) => v.fmt(f),
47            Literal::Char(v) => write!(f, "'{}'", v.escape_debug()),
48            Literal::Int(v) => v.fmt(f),
49            Literal::Float(v) => write!(f, "{:?}", f64::from_bits(*v)),
50            Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()),
51        }
52    }
53}
54
55impl Display for File {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        separate(&self.items, "\n\n")(f)
58    }
59}
60
61impl Display for Attrs {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        let Self { meta } = self;
64        if meta.is_empty() {
65            return Ok(());
66        }
67        "#".fmt(f)?;
68        separate(meta, ", ")(&mut f.delimit(INLINE_SQUARE))?;
69        "\n".fmt(f)
70    }
71}
72
73impl Display for Meta {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        let Self { name, kind } = self;
76        write!(f, "{name}{kind}")
77    }
78}
79
80impl Display for MetaKind {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        match self {
83            MetaKind::Plain => Ok(()),
84            MetaKind::Equals(v) => write!(f, " = {v}"),
85            MetaKind::Func(args) => separate(args, ", ")(f.delimit(INLINE_PARENS)),
86        }
87    }
88}
89
90impl Display for Item {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        let Self { span: _, attrs, vis, kind } = self;
93        attrs.fmt(f)?;
94        vis.fmt(f)?;
95        kind.fmt(f)
96    }
97}
98
99impl Display for ItemKind {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        match self {
102            ItemKind::Alias(v) => v.fmt(f),
103            ItemKind::Const(v) => v.fmt(f),
104            ItemKind::Static(v) => v.fmt(f),
105            ItemKind::Module(v) => v.fmt(f),
106            ItemKind::Function(v) => v.fmt(f),
107            ItemKind::Struct(v) => v.fmt(f),
108            ItemKind::Enum(v) => v.fmt(f),
109            ItemKind::Impl(v) => v.fmt(f),
110            ItemKind::Use(v) => v.fmt(f),
111        }
112    }
113}
114
115impl Display for Generics {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        let Generics { vars } = self;
118        if !vars.is_empty() {
119            separate(vars, ", ")(f.delimit_with("<", ">"))?
120        }
121        Ok(())
122    }
123}
124
125impl Display for Alias {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        let Self { name, from } = self;
128        match from {
129            Some(from) => write!(f, "type {name} = {from};"),
130            None => write!(f, "type {name};"),
131        }
132    }
133}
134
135impl Display for Const {
136    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137        let Self { name, ty, init } = self;
138        write!(f, "const {name}: {ty} = {init}")
139    }
140}
141
142impl Display for Static {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        let Self { mutable, name, ty, init } = self;
145        write!(f, "static {mutable}{name}: {ty} = {init}")
146    }
147}
148
149impl Display for Module {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        let Self { name, file } = self;
152        write!(f, "mod {name}")?;
153        match file {
154            Some(items) => {
155                ' '.fmt(f)?;
156                write!(f.delimit(BRACES), "{items}")
157            }
158            None => Ok(()),
159        }
160    }
161}
162
163impl Display for Function {
164    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165        let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
166        let types = match **args {
167            TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
168            TyKind::Empty => Default::default(),
169            _ => {
170                write!(f, "Invalid function signature: {sign}")?;
171                Default::default()
172            }
173        };
174        let bind = match bind {
175            Pattern::Tuple(patterns) => patterns.as_slice(),
176            _ => {
177                write!(f, "Invalid argument binder: {bind}")?;
178                Default::default()
179            }
180        };
181
182        debug_assert_eq!(bind.len(), types.len());
183        write!(f, "fn {name}{gens} ")?;
184        {
185            let mut f = f.delimit(INLINE_PARENS);
186
187            for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
188                if idx != 0 {
189                    f.write_str(", ")?;
190                }
191                write!(f, "{arg}: {ty}")?;
192            }
193        }
194        if let Some(rety) = rety {
195            write!(f, " -> {rety}")?;
196        }
197        match body {
198            Some(body) => write!(f, " {body}"),
199            None => ';'.fmt(f),
200        }
201    }
202}
203
204impl Display for Struct {
205    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206        let Self { name, gens, kind } = self;
207        write!(f, "struct {name}{gens}{kind}")
208    }
209}
210
211impl Display for StructKind {
212    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213        match self {
214            StructKind::Empty => ';'.fmt(f),
215            StructKind::Tuple(v) => separate(v, ", ")(f.delimit(INLINE_PARENS)),
216            StructKind::Struct(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
217        }
218    }
219}
220
221impl Display for StructMember {
222    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        let Self { vis, name, ty } = self;
224        write!(f, "{vis}{name}: {ty}")
225    }
226}
227
228impl Display for Enum {
229    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230        let Self { name, gens, variants } = self;
231        write!(f, "enum {name}{gens}")?;
232        separate(variants, ",\n")(f.delimit(SPACED_BRACES))
233    }
234}
235
236impl Display for Variant {
237    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238        let Self { name, kind, body } = self;
239        write!(f, "{name}{kind}")?;
240        match body {
241            Some(body) => write!(f, " {body}"),
242            None => Ok(()),
243        }
244    }
245}
246
247impl Display for Impl {
248    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249        let Self { target, body } = self;
250        write!(f, "impl {target} ")?;
251        write!(f.delimit(BRACES), "{body}")
252    }
253}
254
255impl Display for ImplKind {
256    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
257        match self {
258            ImplKind::Type(t) => t.fmt(f),
259            ImplKind::Trait { impl_trait, for_type } => {
260                write!(f, "{impl_trait} for {for_type}")
261            }
262        }
263    }
264}
265
266impl Display for Use {
267    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268        let Self { absolute, tree } = self;
269        f.write_str(if *absolute { "use ::" } else { "use " })?;
270        write!(f, "{tree};")
271    }
272}
273
274impl Display for UseTree {
275    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
276        match self {
277            UseTree::Tree(tree) => separate(tree, ", ")(f.delimit(INLINE_BRACES)),
278            UseTree::Path(path, rest) => write!(f, "{path}::{rest}"),
279            UseTree::Alias(path, name) => write!(f, "{path} as {name}"),
280            UseTree::Name(name) => write!(f, "{name}"),
281            UseTree::Glob => write!(f, "*"),
282        }
283    }
284}
285
286impl Display for Ty {
287    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288        self.kind.fmt(f)
289    }
290}
291
292impl Display for TyKind {
293    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294        match self {
295            TyKind::Never => "!".fmt(f),
296            TyKind::Empty => "()".fmt(f),
297            TyKind::Infer => "_".fmt(f),
298            TyKind::Path(v) => v.fmt(f),
299            TyKind::Array(v) => v.fmt(f),
300            TyKind::Slice(v) => v.fmt(f),
301            TyKind::Tuple(v) => v.fmt(f),
302            TyKind::Ref(v) => v.fmt(f),
303            TyKind::Fn(v) => v.fmt(f),
304        }
305    }
306}
307
308impl Display for TyArray {
309    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
310        let Self { ty, count } = self;
311        write!(f, "[{ty}; {count}]")
312    }
313}
314
315impl Display for TySlice {
316    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
317        let Self { ty } = self;
318        write!(f, "[{ty}]")
319    }
320}
321
322impl Display for TyTuple {
323    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
324        separate(&self.types, ", ")(f.delimit(INLINE_PARENS))
325    }
326}
327
328impl Display for TyRef {
329    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
330        let &Self { count, mutable, ref to } = self;
331        for _ in 0..count {
332            f.write_char('&')?;
333        }
334        write!(f, "{mutable}{to}")
335    }
336}
337
338impl Display for TyFn {
339    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340        let Self { args, rety } = self;
341        write!(f, "fn {args}")?;
342        match rety {
343            Some(v) => write!(f, " -> {v}"),
344            None => Ok(()),
345        }
346    }
347}
348
349impl Display for Path {
350    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
351        let Self { absolute, parts } = self;
352        if *absolute {
353            "::".fmt(f)?;
354        }
355        separate(parts, "::")(f)
356    }
357}
358
359impl Display for PathPart {
360    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
361        match self {
362            PathPart::SuperKw => "super".fmt(f),
363            PathPart::SelfTy => "Self".fmt(f),
364            PathPart::Ident(id) => id.fmt(f),
365        }
366    }
367}
368
369impl Display for Stmt {
370    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
371        let Stmt { span: _, kind, semi } = self;
372        write!(f, "{kind}{semi}")
373    }
374}
375
376impl Display for StmtKind {
377    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
378        match self {
379            StmtKind::Empty => Ok(()),
380            StmtKind::Item(v) => v.fmt(f),
381            StmtKind::Expr(v) => v.fmt(f),
382        }
383    }
384}
385
386impl Display for Semi {
387    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
388        match self {
389            Semi::Terminated => ';'.fmt(f),
390            Semi::Unterminated => Ok(()),
391        }
392    }
393}
394
395impl Display for Expr {
396    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
397        self.kind.fmt(f)
398    }
399}
400
401impl Display for ExprKind {
402    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
403        match self {
404            ExprKind::Empty => "()".fmt(f),
405            ExprKind::Closure(v) => v.fmt(f),
406            ExprKind::Quote(v) => v.fmt(f),
407            ExprKind::Let(v) => v.fmt(f),
408            ExprKind::Match(v) => v.fmt(f),
409            ExprKind::Assign(v) => v.fmt(f),
410            ExprKind::Modify(v) => v.fmt(f),
411            ExprKind::Binary(v) => v.fmt(f),
412            ExprKind::Unary(v) => v.fmt(f),
413            ExprKind::Cast(v) => v.fmt(f),
414            ExprKind::Member(v) => v.fmt(f),
415            ExprKind::Index(v) => v.fmt(f),
416            ExprKind::Structor(v) => v.fmt(f),
417            ExprKind::Path(v) => v.fmt(f),
418            ExprKind::Literal(v) => v.fmt(f),
419            ExprKind::Array(v) => v.fmt(f),
420            ExprKind::ArrayRep(v) => v.fmt(f),
421            ExprKind::AddrOf(v) => v.fmt(f),
422            ExprKind::Block(v) => v.fmt(f),
423            ExprKind::Group(v) => v.fmt(f),
424            ExprKind::Tuple(v) => v.fmt(f),
425            ExprKind::While(v) => v.fmt(f),
426            ExprKind::If(v) => v.fmt(f),
427            ExprKind::For(v) => v.fmt(f),
428            ExprKind::Break(v) => v.fmt(f),
429            ExprKind::Return(v) => v.fmt(f),
430            ExprKind::Continue => "continue".fmt(f),
431        }
432    }
433}
434
435impl Display for Closure {
436    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
437        let Self { arg, body } = self;
438        match arg.as_ref() {
439            Pattern::Tuple(args) => separate(args, ", ")(f.delimit_with("|", "|")),
440            _ => arg.fmt(f),
441        }?;
442        write!(f, " {body}")
443    }
444}
445
446impl Display for Quote {
447    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
448        let Self { quote } = self;
449        write!(f, "`{quote}`")
450    }
451}
452
453impl Display for Let {
454    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
455        let Self { mutable, name, ty, init } = self;
456        write!(f, "let {mutable}{name}")?;
457        if let Some(value) = ty {
458            write!(f, ": {value}")?;
459        }
460        if let Some(value) = init {
461            write!(f, " = {value}")?;
462        }
463        Ok(())
464    }
465}
466
467impl Display for Pattern {
468    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
469        match self {
470            Pattern::Name(sym) => sym.fmt(f),
471            Pattern::Path(path) => path.fmt(f),
472            Pattern::Literal(literal) => literal.fmt(f),
473            Pattern::Rest(Some(name)) => write!(f, "..{name}"),
474            Pattern::Rest(None) => "..".fmt(f),
475            Pattern::Ref(mutability, pattern) => write!(f, "&{mutability}{pattern}"),
476            Pattern::RangeExc(head, tail) => write!(f, "{head}..{tail}"),
477            Pattern::RangeInc(head, tail) => write!(f, "{head}..={tail}"),
478            Pattern::Tuple(patterns) => separate(patterns, ", ")(f.delimit(INLINE_PARENS)),
479            Pattern::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
480            Pattern::Struct(path, items) => {
481                write!(f, "{path} ")?;
482                let f = &mut f.delimit(INLINE_BRACES);
483                for (idx, (name, item)) in items.iter().enumerate() {
484                    if idx != 0 {
485                        f.write_str(", ")?;
486                    }
487                    write!(f, "{name}")?;
488                    if let Some(pattern) = item {
489                        write!(f, ": {pattern}")?
490                    }
491                }
492                Ok(())
493            }
494            Pattern::TupleStruct(path, items) => {
495                write!(f, "{path}")?;
496                separate(items, ", ")(f.delimit(INLINE_PARENS))
497            }
498        }
499    }
500}
501
502impl Display for Match {
503    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
504        let Self { scrutinee, arms } = self;
505        write!(f, "match {scrutinee} ")?;
506        separate(arms, ",\n")(f.delimit(BRACES))
507    }
508}
509
510impl Display for MatchArm {
511    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
512        let Self(pat, expr) = self;
513        write!(f, "{pat} => {expr}")
514    }
515}
516
517impl Display for Assign {
518    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
519        let Self { parts } = self;
520        write!(f, "{} = {}", parts.0, parts.1)
521    }
522}
523
524impl Display for Modify {
525    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
526        let Self { kind, parts } = self;
527        write!(f, "{} {kind} {}", parts.0, parts.1)
528    }
529}
530
531impl Display for ModifyKind {
532    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
533        match self {
534            ModifyKind::Mul => "*=",
535            ModifyKind::Div => "/=",
536            ModifyKind::Rem => "%=",
537            ModifyKind::Add => "+=",
538            ModifyKind::Sub => "-=",
539            ModifyKind::And => "&=",
540            ModifyKind::Or => "|=",
541            ModifyKind::Xor => "^=",
542            ModifyKind::Shl => "<<=",
543            ModifyKind::Shr => ">>=",
544        }
545        .fmt(f)
546    }
547}
548
549impl Display for Binary {
550    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
551        let Self { kind, parts } = self;
552        let (head, tail) = parts.borrow();
553        match kind {
554            BinaryKind::Call => write!(f, "{head}{tail}"),
555            _ => write!(f, "{head} {kind} {tail}"),
556        }
557    }
558}
559
560impl Display for BinaryKind {
561    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562        match self {
563            BinaryKind::Lt => "<",
564            BinaryKind::LtEq => "<=",
565            BinaryKind::Equal => "==",
566            BinaryKind::NotEq => "!=",
567            BinaryKind::GtEq => ">=",
568            BinaryKind::Gt => ">",
569            BinaryKind::RangeExc => "..",
570            BinaryKind::RangeInc => "..=",
571            BinaryKind::LogAnd => "&&",
572            BinaryKind::LogOr => "||",
573            BinaryKind::LogXor => "^^",
574            BinaryKind::BitAnd => "&",
575            BinaryKind::BitOr => "|",
576            BinaryKind::BitXor => "^",
577            BinaryKind::Shl => "<<",
578            BinaryKind::Shr => ">>",
579            BinaryKind::Add => "+",
580            BinaryKind::Sub => "-",
581            BinaryKind::Mul => "*",
582            BinaryKind::Div => "/",
583            BinaryKind::Rem => "%",
584            BinaryKind::Call => "()",
585        }
586        .fmt(f)
587    }
588}
589
590impl Display for Unary {
591    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
592        let Self { kind, tail } = self;
593        write!(f, "{kind}{tail}")
594    }
595}
596
597impl Display for UnaryKind {
598    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
599        match self {
600            UnaryKind::Loop => "loop ",
601            UnaryKind::Deref => "*",
602            UnaryKind::Neg => "-",
603            UnaryKind::Not => "!",
604            UnaryKind::RangeExc => "..",
605            UnaryKind::RangeInc => "..=",
606            UnaryKind::At => "@",
607            UnaryKind::Tilde => "~",
608        }
609        .fmt(f)
610    }
611}
612
613impl Display for Cast {
614    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
615        let Self { head, ty } = self;
616        write!(f, "{head} as {ty}")
617    }
618}
619
620impl Display for Member {
621    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
622        let Self { head, kind } = self;
623        write!(f, "{head}.{kind}")
624    }
625}
626
627impl Display for MemberKind {
628    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
629        match self {
630            MemberKind::Call(name, args) => write!(f, "{name}{args}"),
631            MemberKind::Struct(name) => write!(f, "{name}"),
632            MemberKind::Tuple(name) => write!(f, "{name}"),
633        }
634    }
635}
636
637impl Display for Index {
638    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
639        let Self { head, indices } = self;
640        write!(f, "{head}")?;
641        separate(indices, ", ")(f.delimit(INLINE_SQUARE))
642    }
643}
644
645impl Display for Structor {
646    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
647        let Self { to, init } = self;
648        write!(f, "{to} ")?;
649        separate(init, ", ")(f.delimit(INLINE_BRACES))
650    }
651}
652
653impl Display for Fielder {
654    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
655        let Self { name, init } = self;
656        write!(f, "{name}")?;
657        if let Some(init) = init {
658            write!(f, ": {init}")?;
659        }
660        Ok(())
661    }
662}
663
664impl Display for Array {
665    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
666        separate(&self.values, ", ")(f.delimit(INLINE_SQUARE))
667    }
668}
669
670impl Display for ArrayRep {
671    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
672        let Self { value, repeat } = self;
673        write!(f, "[{value}; {repeat}]")
674    }
675}
676
677impl Display for AddrOf {
678    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
679        let Self { mutable, expr } = self;
680        write!(f, "&{mutable}{expr}")
681    }
682}
683
684impl Display for Block {
685    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
686        let Self { stmts } = self;
687
688        match stmts.as_slice() {
689            [] => "{}".fmt(f),
690            stmts => separate(stmts, "\n")(f.delimit(BRACES)),
691        }
692    }
693}
694
695impl Display for Group {
696    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
697        write!(f, "({})", self.expr)
698    }
699}
700
701impl Display for Tuple {
702    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
703        let Self { exprs } = self;
704
705        match exprs.as_slice() {
706            [] => write!(f, "()"),
707            [expr] => write!(f, "({expr},)"),
708            exprs => separate(exprs, ", ")(f.delimit(INLINE_PARENS)),
709        }
710    }
711}
712
713impl Display for While {
714    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
715        let Self { cond, pass, fail } = self;
716        write!(f, "while {cond} {pass}{fail}")
717    }
718}
719
720impl Display for If {
721    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
722        let Self { cond, pass, fail } = self;
723        write!(f, "if {cond} {pass}{fail}")
724    }
725}
726
727impl Display for For {
728    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
729        let Self { bind, cond, pass, fail } = self;
730        write!(f, "for {bind} in {cond} {pass}{fail}")
731    }
732}
733
734impl Display for Else {
735    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
736        match &self.body {
737            Some(body) => write!(f, " else {body}"),
738            _ => Ok(()),
739        }
740    }
741}
742
743impl Display for Break {
744    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
745        write!(f, "break")?;
746        match &self.body {
747            Some(body) => write!(f, " {body}"),
748            _ => Ok(()),
749        }
750    }
751}
752
753impl Display for Return {
754    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
755        write!(f, "return")?;
756        match &self.body {
757            Some(body) => write!(f, " {body}"),
758            _ => Ok(()),
759        }
760    }
761}