1use crate::{span::Spanned, syntax::*};
2use core::fmt;
3use std::fmt::{Display, Formatter};
4
5use itertools::Itertools;
6
7struct FormatFn<F: (Fn(&mut Formatter) -> fmt::Result)>(F);
9
10impl<F: Fn(&mut Formatter) -> fmt::Result> Display for FormatFn<F> {
11 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
12 (self.0)(f)
13 }
14}
15
16impl<T: Display> Display for Spanned<T> {
17 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
18 self.node().fmt(f)
19 }
20}
21
22struct Indent<T: Display>(pub T);
23
24impl<T: Display> Display for Indent<T> {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 let indent = " ";
27 let inner_display = self.0.to_string();
28 let fmt = inner_display
29 .lines()
30 .format_with("\n", |l, f| f(&format_args!("{indent}{l}")));
31 write!(f, "{}", fmt)?;
32 Ok(())
33 }
34}
35
36impl Display for TranslationUnit {
37 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
38 #[cfg(feature = "imports")]
39 if !self.imports.is_empty() {
40 for import in &self.imports {
41 writeln!(f, "import {import}\n")?;
42 }
43 }
44 if !self.global_directives.is_empty() {
45 let directives = self.global_directives.iter().format("\n");
46 write!(f, "{directives}\n\n")?;
47 }
48 let declarations = self
49 .global_declarations
50 .iter()
51 .filter(|decl| !matches!(decl, GlobalDeclaration::Void))
52 .format("\n\n");
53 writeln!(f, "{declarations}")
54 }
55}
56
57impl Display for Ident {
58 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
59 write!(f, "{}", self.name())
60 }
61}
62
63#[cfg(feature = "imports")]
64impl Display for Import {
65 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
66 #[cfg(feature = "attributes")]
67 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
68 let path = self
69 .path
70 .iter()
71 .map(|segment| match segment.to_str() {
72 Some(".") => "self",
73 Some("..") => "super",
74 Some(str) => str,
75 _ => "?",
76 })
77 .format("::");
78 let absolute = if self.path.has_root() {
79 "package::"
80 } else {
81 ""
82 };
83 let content = &self.content;
84 write!(f, "{absolute}{path}::{content};")
85 }
86}
87
88#[cfg(feature = "imports")]
89impl Display for ImportContent {
90 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
91 match self {
92 ImportContent::Item(item) => {
93 write!(f, "{}", item.ident)?;
94 if let Some(rename) = &item.rename {
95 write!(f, " as {rename}")?;
96 }
97 Ok(())
98 }
99 ImportContent::Collection(coll) => {
100 let coll = coll.iter().format(", ");
101 write!(f, "{{ {coll} }}")
102 }
103 }
104 }
105}
106
107impl Display for GlobalDirective {
108 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
109 match self {
110 GlobalDirective::Diagnostic(print) => write!(f, "{}", print),
111 GlobalDirective::Enable(print) => write!(f, "{}", print),
112 GlobalDirective::Requires(print) => write!(f, "{}", print),
113 }
114 }
115}
116
117impl Display for DiagnosticDirective {
118 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
119 #[cfg(feature = "attributes")]
120 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
121 let severity = &self.severity;
122 let rule = &self.rule_name;
123 write!(f, "diagnostic ({severity}, {rule});")
124 }
125}
126
127impl Display for DiagnosticSeverity {
128 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
129 match self {
130 Self::Error => write!(f, "error"),
131 Self::Warning => write!(f, "warning"),
132 Self::Info => write!(f, "info"),
133 Self::Off => write!(f, "off"),
134 }
135 }
136}
137
138impl Display for EnableDirective {
139 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
140 #[cfg(feature = "attributes")]
141 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
142 let exts = self.extensions.iter().format(", ");
143 write!(f, "enable {exts};")
144 }
145}
146
147impl Display for RequiresDirective {
148 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
149 #[cfg(feature = "attributes")]
150 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
151 let exts = self.extensions.iter().format(", ");
152 write!(f, "requires {exts};")
153 }
154}
155
156impl Display for GlobalDeclaration {
157 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
158 match self {
159 GlobalDeclaration::Void => write!(f, ";"),
160 GlobalDeclaration::Declaration(print) => write!(f, "{}", print),
161 GlobalDeclaration::TypeAlias(print) => write!(f, "{}", print),
162 GlobalDeclaration::Struct(print) => write!(f, "{}", print),
163 GlobalDeclaration::Function(print) => write!(f, "{}", print),
164 GlobalDeclaration::ConstAssert(print) => write!(f, "{}", print),
165 }
166 }
167}
168
169impl Display for Declaration {
170 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
171 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
172 let kind = &self.kind;
173 let name = &self.ident;
174 let typ = self
175 .ty
176 .iter()
177 .format_with("", |ty, f| f(&format_args!(": {}", ty)));
178 let init = self
179 .initializer
180 .iter()
181 .format_with("", |ty, f| f(&format_args!(" = {}", ty)));
182 write!(f, "{kind} {name}{typ}{init};")
183 }
184}
185
186impl Display for DeclarationKind {
187 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
188 match self {
189 Self::Const => write!(f, "const"),
190 Self::Override => write!(f, "override"),
191 Self::Let => write!(f, "let"),
192 Self::Var(addr_space) => match addr_space {
193 Some(addr_space) => write!(f, "var<{addr_space}>"),
194 None => write!(f, "var"),
195 },
196 }
197 }
198}
199
200impl Display for AddressSpace {
201 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
202 match self {
203 Self::Function => write!(f, "function"),
204 Self::Private => write!(f, "private"),
205 Self::Workgroup => write!(f, "workgroup"),
206 Self::Uniform => write!(f, "uniform"),
207 Self::Storage(access_mode) => match access_mode {
208 Some(access_mode) => write!(f, "storage, {access_mode}"),
209 None => write!(f, "storage"),
210 },
211 Self::Handle => write!(f, "handle"),
212 }
213 }
214}
215
216impl Display for AccessMode {
217 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
218 match self {
219 Self::Read => write!(f, "read"),
220 Self::Write => write!(f, "write"),
221 Self::ReadWrite => write!(f, "read_write"),
222 }
223 }
224}
225
226impl Display for TypeAlias {
227 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
228 #[cfg(feature = "attributes")]
229 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
230 let name = &self.ident;
231 let typ = &self.ty;
232 write!(f, "alias {name} = {typ};")
233 }
234}
235
236impl Display for Struct {
237 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
238 #[cfg(feature = "attributes")]
239 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
240 let name = &self.ident;
241 let members = Indent(self.members.iter().format(",\n"));
242 write!(f, "struct {name} {{\n{members}\n}}")
243 }
244}
245
246impl Display for StructMember {
247 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
248 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
249 let name = &self.ident;
250 let typ = &self.ty;
251 write!(f, "{name}: {typ}")
252 }
253}
254
255impl Display for Function {
256 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
257 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
258 let name = &self.ident;
259 let params = self.parameters.iter().format(", ");
260 let ret_ty = self.return_type.iter().format_with("", |ty, f| {
261 f(&FormatFn(|f: &mut Formatter| {
262 write!(f, "-> ")?;
263 write!(f, "{}", fmt_attrs(&self.return_attributes, true))?;
264 write!(f, "{ty} ")?;
265 Ok(())
266 }))
267 });
268 let body = &self.body;
269 write!(f, "fn {name}({params}) {ret_ty}{body}")
270 }
271}
272
273impl Display for FormalParameter {
274 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
275 write!(f, "{}", fmt_attrs(&self.attributes, true))?;
276 let name = &self.ident;
277 let typ = &self.ty;
278 write!(f, "{name}: {typ}")
279 }
280}
281
282impl Display for ConstAssert {
283 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
284 #[cfg(feature = "attributes")]
285 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
286 let expr = &self.expression;
287 write!(f, "const_assert {expr};",)
288 }
289}
290
291impl Display for BuiltinValue {
292 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
293 match self {
294 Self::VertexIndex => write!(f, "vertex_index"),
295 Self::InstanceIndex => write!(f, "instance_index"),
296 Self::Position => write!(f, "position"),
297 Self::FrontFacing => write!(f, "front_facing"),
298 Self::FragDepth => write!(f, "frag_depth"),
299 Self::SampleIndex => write!(f, "sample_index"),
300 Self::SampleMask => write!(f, "sample_mask"),
301 Self::LocalInvocationId => write!(f, "local_invocation_id"),
302 Self::LocalInvocationIndex => write!(f, "local_invocation_index"),
303 Self::GlobalInvocationId => write!(f, "global_invocation_id"),
304 Self::WorkgroupId => write!(f, "workgroup_id"),
305 Self::NumWorkgroups => write!(f, "num_workgroups"),
306 }
307 }
308}
309
310impl Display for InterpolationType {
311 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
312 match self {
313 InterpolationType::Perspective => write!(f, "perspective"),
314 InterpolationType::Linear => write!(f, "linear"),
315 InterpolationType::Flat => write!(f, "flat"),
316 }
317 }
318}
319
320impl Display for InterpolationSampling {
321 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
322 match self {
323 Self::Center => write!(f, "center"),
324 Self::Centroid => write!(f, "centroid"),
325 Self::Sample => write!(f, "sample"),
326 Self::First => write!(f, "first"),
327 Self::Either => write!(f, "either"),
328 }
329 }
330}
331
332impl Display for Attribute {
333 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
334 match self {
335 Attribute::Align(e1) => write!(f, "@align({e1})"),
336 Attribute::Binding(e1) => write!(f, "@binding({e1})"),
337 Attribute::BlendSrc(e1) => write!(f, "@blend_src({e1})"),
338 Attribute::Builtin(e1) => write!(f, "@builtin({e1})"),
339 Attribute::Const => write!(f, "@const"),
340 Attribute::Diagnostic(DiagnosticAttribute { severity, rule }) => {
341 write!(f, "@diagnostic({severity}, {rule})")
342 }
343 Attribute::Group(e1) => write!(f, "@group({e1})"),
344 Attribute::Id(e1) => write!(f, "@id({e1})"),
345 Attribute::Interpolate(InterpolateAttribute { ty, sampling }) => {
346 if let Some(sampling) = sampling {
347 write!(f, "@interpolate({ty}, {sampling})")
348 } else {
349 write!(f, "@interpolate({ty})")
350 }
351 }
352 Attribute::Invariant => write!(f, "@invariant"),
353 Attribute::Location(e1) => write!(f, "@location({e1})"),
354 Attribute::MustUse => write!(f, "@must_use"),
355 Attribute::Size(e1) => write!(f, "@size({e1})"),
356 Attribute::WorkgroupSize(WorkgroupSizeAttribute { x, y, z }) => {
357 let xyz = std::iter::once(x).chain(y).chain(z).format(", ");
358 write!(f, "@workgroup_size({xyz})")
359 }
360 Attribute::Vertex => write!(f, "@vertex"),
361 Attribute::Fragment => write!(f, "@fragment"),
362 Attribute::Compute => write!(f, "@compute"),
363 #[cfg(feature = "condcomp")]
364 Attribute::If(e1) => write!(f, "@if({e1})"),
365 #[cfg(feature = "generics")]
366 Attribute::Type(e1) => write!(f, "@type({e1})"),
367 Attribute::Custom(custom) => {
368 let name = &custom.name;
369 let args = custom.arguments.iter().format_with("", |args, f| {
370 f(&format_args!("({})", args.iter().format(", ")))
371 });
372 write!(f, "@{name}{args}")
373 }
374 }
375 }
376}
377
378#[cfg(feature = "generics")]
379impl Display for TypeConstraint {
380 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
381 let name = &self.ident;
382 let variants = self.variants.iter().format(" | ");
383 write!(f, "{name}, {variants}")
384 }
385}
386
387fn fmt_attrs(attrs: &[Attribute], inline: bool) -> impl fmt::Display + '_ {
388 FormatFn(move |f| {
389 let print = attrs.iter().format(" ");
390 let suffix = if attrs.is_empty() {
391 ""
392 } else if inline {
393 " "
394 } else {
395 "\n"
396 };
397 write!(f, "{print}{suffix}")
398 })
399}
400
401impl Display for Expression {
402 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
403 match self {
404 Expression::Literal(print) => write!(f, "{print}"),
405 Expression::Parenthesized(print) => {
406 write!(f, "{print}")
407 }
408 Expression::NamedComponent(print) => write!(f, "{print}"),
409 Expression::Indexing(print) => write!(f, "{print}"),
410 Expression::Unary(print) => write!(f, "{print}"),
411 Expression::Binary(print) => write!(f, "{print}"),
412 Expression::FunctionCall(print) => write!(f, "{print}"),
413 Expression::TypeOrIdentifier(print) => write!(f, "{print}"),
414 }
415 }
416}
417
418impl Display for LiteralExpression {
419 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
420 match self {
421 LiteralExpression::Bool(true) => write!(f, "true"),
422 LiteralExpression::Bool(false) => write!(f, "false"),
423 LiteralExpression::AbstractInt(num) => write!(f, "{num}"),
424 LiteralExpression::AbstractFloat(num) => write!(f, "{num:?}"), LiteralExpression::I32(num) => write!(f, "{num}i"),
426 LiteralExpression::U32(num) => write!(f, "{num}u"),
427 LiteralExpression::F32(num) => write!(f, "{num}f"),
428 LiteralExpression::F16(num) => write!(f, "{num}h"),
429 }
430 }
431}
432
433impl Display for ParenthesizedExpression {
434 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
435 let expr = &self.expression;
436 write!(f, "({expr})")
437 }
438}
439
440impl Display for NamedComponentExpression {
441 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
442 let base = &self.base;
443 let component = &self.component;
444 write!(f, "{base}.{component}")
445 }
446}
447
448impl Display for IndexingExpression {
449 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
450 let base = &self.base;
451 let index = &self.index;
452 write!(f, "{base}[{index}]")
453 }
454}
455
456impl Display for UnaryExpression {
457 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
458 let operator = &self.operator;
459 let operand = &self.operand;
460 write!(f, "{operator}{operand}")
461 }
462}
463
464impl Display for UnaryOperator {
465 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
466 match self {
467 UnaryOperator::LogicalNegation => write!(f, "!"),
468 UnaryOperator::Negation => write!(f, "-"),
469 UnaryOperator::BitwiseComplement => write!(f, "~"),
470 UnaryOperator::AddressOf => write!(f, "&"),
471 UnaryOperator::Indirection => write!(f, "*"),
472 }
473 }
474}
475
476impl Display for BinaryExpression {
477 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
478 let operator = &self.operator;
479 let left = &self.left;
480 let right = &self.right;
481 write!(f, "{left} {operator} {right}")
482 }
483}
484
485impl Display for BinaryOperator {
486 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
487 match self {
488 BinaryOperator::ShortCircuitOr => write!(f, "||"),
489 BinaryOperator::ShortCircuitAnd => write!(f, "&&"),
490 BinaryOperator::Addition => write!(f, "+"),
491 BinaryOperator::Subtraction => write!(f, "-"),
492 BinaryOperator::Multiplication => write!(f, "*"),
493 BinaryOperator::Division => write!(f, "/"),
494 BinaryOperator::Remainder => write!(f, "%"),
495 BinaryOperator::Equality => write!(f, "=="),
496 BinaryOperator::Inequality => write!(f, "!="),
497 BinaryOperator::LessThan => write!(f, "<"),
498 BinaryOperator::LessThanEqual => write!(f, "<="),
499 BinaryOperator::GreaterThan => write!(f, ">"),
500 BinaryOperator::GreaterThanEqual => write!(f, ">="),
501 BinaryOperator::BitwiseOr => write!(f, "|"),
502 BinaryOperator::BitwiseAnd => write!(f, "&"),
503 BinaryOperator::BitwiseXor => write!(f, "^"),
504 BinaryOperator::ShiftLeft => write!(f, "<<"),
505 BinaryOperator::ShiftRight => write!(f, ">>"),
506 }
507 }
508}
509
510impl Display for FunctionCall {
511 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
512 let ty = &self.ty;
513 let args = self.arguments.iter().format(", ");
514 write!(f, "{ty}({args})")
515 }
516}
517
518impl Display for TypeExpression {
519 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
520 let name = &self.ident;
521 let tplt = fmt_template(&self.template_args);
522 write!(f, "{name}{tplt}")
523 }
524}
525
526impl Display for TemplateArg {
527 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
528 let expr = &self.expression;
529 write!(f, "{expr}")
530 }
531}
532
533fn fmt_template(tplt: &Option<Vec<TemplateArg>>) -> impl fmt::Display + '_ {
534 tplt.iter().format_with("", |tplt, f| {
535 f(&format_args!("<{}>", tplt.iter().format(", ")))
536 })
537}
538
539impl Display for Statement {
540 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
541 match self {
542 Statement::Void => write!(f, ";"),
543 Statement::Compound(print) => write!(f, "{print}"),
544 Statement::Assignment(print) => write!(f, "{print}"),
545 Statement::Increment(print) => write!(f, "{print}"),
546 Statement::Decrement(print) => write!(f, "{print}"),
547 Statement::If(print) => write!(f, "{print}"),
548 Statement::Switch(print) => write!(f, "{print}"),
549 Statement::Loop(print) => write!(f, "{print}"),
550 Statement::For(print) => write!(f, "{print}"),
551 Statement::While(print) => write!(f, "{print}"),
552 Statement::Break(print) => write!(f, "{print}"),
553 Statement::Continue(print) => write!(f, "{print}"),
554 Statement::Return(print) => write!(f, "{print}"),
555 Statement::Discard(print) => write!(f, "{print}"),
556 Statement::FunctionCall(print) => write!(f, "{print}"),
557 Statement::ConstAssert(print) => write!(f, "{print}"),
558 Statement::Declaration(print) => write!(f, "{print}"),
559 }
560 }
561}
562
563impl Display for CompoundStatement {
564 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
565 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
566 let stmts = Indent(
567 self.statements
568 .iter()
569 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
570 .format("\n"),
571 );
572 write!(f, "{{\n{stmts}\n}}")
573 }
574}
575
576impl Display for AssignmentStatement {
577 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
578 #[cfg(feature = "attributes")]
579 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
580 let operator = &self.operator;
581 let lhs = &self.lhs;
582 let rhs = &self.rhs;
583 write!(f, "{lhs} {operator} {rhs};")
584 }
585}
586
587impl Display for AssignmentOperator {
588 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
589 match self {
590 AssignmentOperator::Equal => write!(f, "="),
591 AssignmentOperator::PlusEqual => write!(f, "+="),
592 AssignmentOperator::MinusEqual => write!(f, "-="),
593 AssignmentOperator::TimesEqual => write!(f, "*="),
594 AssignmentOperator::DivisionEqual => write!(f, "/="),
595 AssignmentOperator::ModuloEqual => write!(f, "%="),
596 AssignmentOperator::AndEqual => write!(f, "&="),
597 AssignmentOperator::OrEqual => write!(f, "|="),
598 AssignmentOperator::XorEqual => write!(f, "^="),
599 AssignmentOperator::ShiftRightAssign => write!(f, ">>="),
600 AssignmentOperator::ShiftLeftAssign => write!(f, "<<="),
601 }
602 }
603}
604
605impl Display for IncrementStatement {
606 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
607 #[cfg(feature = "attributes")]
608 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
609 let expr = &self.expression;
610 write!(f, "{expr}++;")
611 }
612}
613
614impl Display for DecrementStatement {
615 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
616 #[cfg(feature = "attributes")]
617 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
618 let expr = &self.expression;
619 write!(f, "{expr}--;")
620 }
621}
622
623impl Display for IfStatement {
624 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
625 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
626 let if_clause = &self.if_clause;
627 write!(f, "{if_clause}")?;
628 for else_if_clause in self.else_if_clauses.iter() {
629 write!(f, "\n{else_if_clause}")?;
630 }
631 if let Some(else_clause) = &self.else_clause {
632 write!(f, "\n{else_clause}")?;
633 }
634 Ok(())
635 }
636}
637
638impl Display for IfClause {
639 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
640 let expr = &self.expression;
641 let stmt = &self.body;
642 write!(f, "if {expr} {stmt}")
643 }
644}
645
646impl Display for ElseIfClause {
647 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
648 #[cfg(feature = "attributes")]
649 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
650 let expr = &self.expression;
651 let stmt = &self.body;
652 write!(f, "else if {expr} {stmt}")
653 }
654}
655
656impl Display for ElseClause {
657 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
658 #[cfg(feature = "attributes")]
659 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
660 let stmt = &self.body;
661 write!(f, "else {stmt}")
662 }
663}
664
665impl Display for SwitchStatement {
666 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
667 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
668 let expr = &self.expression;
669 let body_attrs = fmt_attrs(&self.body_attributes, false);
670 let clauses = Indent(self.clauses.iter().format("\n"));
671 write!(f, "switch {expr} {body_attrs}{{\n{clauses}\n}}")
672 }
673}
674
675impl Display for SwitchClause {
676 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
677 #[cfg(feature = "attributes")]
678 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
679 let cases = self.case_selectors.iter().format(", ");
680 let body = &self.body;
681 write!(f, "case {cases} {body}")
682 }
683}
684
685impl Display for CaseSelector {
686 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
687 match self {
688 CaseSelector::Default => write!(f, "default"),
689 CaseSelector::Expression(expr) => {
690 write!(f, "{}", expr)
691 }
692 }
693 }
694}
695
696impl Display for LoopStatement {
697 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
698 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
699 let body_attrs = fmt_attrs(&self.body.attributes, false);
700 let stmts = Indent(
701 self.body
702 .statements
703 .iter()
704 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
705 .format("\n"),
706 );
707 let continuing = self
708 .continuing
709 .iter()
710 .format_with("", |cont, f| f(&format_args!("{}\n", Indent(cont))));
711 write!(f, "loop {body_attrs}{{\n{stmts}\n{continuing}}}")
712 }
713}
714
715impl Display for ContinuingStatement {
716 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
717 #[cfg(feature = "attributes")]
718 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
719 let body_attrs = fmt_attrs(&self.body.attributes, false);
720 let stmts = Indent(
721 self.body
722 .statements
723 .iter()
724 .filter(|stmt| !matches!(stmt.node(), Statement::Void))
725 .format("\n"),
726 );
727 let break_if = self
728 .break_if
729 .iter()
730 .format_with("", |stmt, f| f(&format_args!("{}\n", Indent(stmt))));
731 write!(f, "continuing {body_attrs}{{\n{stmts}\n{break_if}}}")
732 }
733}
734
735impl Display for BreakIfStatement {
736 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
737 #[cfg(feature = "attributes")]
738 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
739 let expr = &self.expression;
740 write!(f, "break if {expr};")
741 }
742}
743
744impl Display for ForStatement {
745 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
746 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
747 let mut init = self
748 .initializer
749 .as_ref()
750 .map(|stmt| format!("{}", stmt))
751 .unwrap_or_default();
752 if init.ends_with(';') {
753 init.pop();
754 }
755 let cond = self
756 .condition
757 .iter()
758 .format_with("", |expr, f| f(&format_args!("{expr}")));
759 let mut updt = self
760 .update
761 .as_ref()
762 .map(|stmt| format!("{}", stmt))
763 .unwrap_or_default();
764 if updt.ends_with(';') {
765 updt.pop();
766 }
767 let body = &self.body;
768 write!(f, "for ({init}; {cond}; {updt}) {body}")
769 }
770}
771
772impl Display for WhileStatement {
773 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
774 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
775 let cond = &self.condition;
776 let body = &self.body;
777 write!(f, "while ({cond}) {body}")
778 }
779}
780
781impl Display for BreakStatement {
782 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
783 #[cfg(feature = "attributes")]
784 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
785 write!(f, "break;")
786 }
787}
788
789impl Display for ContinueStatement {
790 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
791 #[cfg(feature = "attributes")]
792 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
793 write!(f, "continue;")
794 }
795}
796
797impl Display for ReturnStatement {
798 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
799 #[cfg(feature = "attributes")]
800 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
801 let expr = self
802 .expression
803 .iter()
804 .format_with("", |expr, f| f(&format_args!(" {expr}")));
805 write!(f, "return{expr};")
806 }
807}
808
809impl Display for DiscardStatement {
810 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
811 #[cfg(feature = "attributes")]
812 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
813 write!(f, "discard;")
814 }
815}
816
817impl Display for FunctionCallStatement {
818 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
819 #[cfg(feature = "attributes")]
820 write!(f, "{}", fmt_attrs(&self.attributes, false))?;
821 let call = &self.call;
822 write!(f, "{call};")
823 }
824}