1#![feature(never_type, decl_macro, coverage_attribute, macro_metavar_expr_concat)]
5
6mod whitespace;
8mod str;
9mod output;
10
11pub use rustidy_macros::Print;
13pub use self::output::PrintOutput;
14
15use {core::marker::PhantomData, rustidy_util::{ArenaData, ArenaIdx, AstStr}};
17
18pub trait Print: Sized {
20 fn print(&self, f: &mut PrintFmt);
22
23 fn print_non_ws(&self, f: &mut PrintFmt);
28
29 fn print_to(&self, p: impl FnOnce(&Self,&mut PrintFmt)) -> PrintOutput {
31 let mut f = PrintFmt::new();
32 p(self, &mut f);
33 f.output
34 }
35}
36
37impl<T: Print> Print for &'_ T {
38 fn print(&self, f: &mut PrintFmt) {
39 (**self).print(f);
40 }
41
42 fn print_non_ws(&self, f: &mut PrintFmt) {
43 (**self).print(f);
44 }
45}
46
47impl<T: Print> Print for Box<T> {
48 fn print(&self, f: &mut PrintFmt) {
49 (**self).print(f);
50 }
51
52 fn print_non_ws(&self, f: &mut PrintFmt) {
53 (**self).print(f);
54 }
55}
56
57impl<T: Print> Print for Option<T> {
58 fn print(&self, f: &mut PrintFmt) {
59 if let Some(value) = self {
60 value.print(f);
61 }
62 }
63
64 fn print_non_ws(&self, f: &mut PrintFmt) {
65 if let Some(value) = self {
66 value.print_non_ws(f);
67 }
68 }
69}
70
71impl<T: Print> Print for Vec<T> {
72 fn print(&self, f: &mut PrintFmt) {
73 for value in self {
74 value.print(f);
75 }
76 }
77
78 fn print_non_ws(&self, f: &mut PrintFmt) {
79 for value in self {
80 value.print_non_ws(f);
81 }
82 }
83}
84
85impl Print for ! {
86 fn print(&self, _f: &mut PrintFmt) {
87 *self
88 }
89
90 fn print_non_ws(&self, _f: &mut PrintFmt) {
91 *self
92 }
93}
94
95impl<T> Print for PhantomData<T> {
96 fn print(&self, _f: &mut PrintFmt) {}
97
98 fn print_non_ws(&self, _f: &mut PrintFmt) {}
99}
100
101impl Print for () {
102 fn print(&self, _f: &mut PrintFmt) {}
103
104 fn print_non_ws(&self, _f: &mut PrintFmt) {}
105}
106
107macro tuple_impl(
108 $N:literal, $($T:ident),* $(,)?
109) {
110 #[automatically_derived]
111 impl< $($T: Print,)* > Print for ( $($T,)* ) {
112 #[expect(non_snake_case)]
113 fn print(&self, f: &mut PrintFmt) {
114 let ( $($T,)* ) = self;
115 $(
116 $T.print(f);
117 )*
118 }
119
120 #[expect(non_snake_case)]
121 fn print_non_ws(&self, f: &mut PrintFmt) {
122 let ( $($T,)* ) = self;
123 $(
124 $T.print_non_ws(f);
125 )*
126 }
127 }
128}
129
130tuple_impl! { 1, T0 }
131tuple_impl! { 2, T0, T1 }
132tuple_impl! { 3, T0, T1, T2 }
133
134impl Print for AstStr {
135 fn print(&self, f: &mut PrintFmt) {
136 str::write(self, &mut f.output);
137 }
138
139 fn print_non_ws(&self, f: &mut PrintFmt) {
140 str::write(self, &mut f.output);
141 }
142}
143
144impl<T: ArenaData + Print> Print for ArenaIdx<T> {
145 fn print(&self, f: &mut PrintFmt) {
146 (**self).print(f);
147 }
148
149 fn print_non_ws(&self, f: &mut PrintFmt) {
150 (**self).print(f);
151 }
152}
153
154#[derive(Debug)]
156pub struct PrintFmt {
157 output: PrintOutput,
158}
159
160impl PrintFmt {
161 #[must_use]
163 pub const fn new() -> Self {
164 Self { output: PrintOutput::Empty }
165 }
166
167 #[must_use]
169 pub const fn output(&self) -> &PrintOutput {
170 &self.output
171 }
172}
173
174impl Default for PrintFmt {
175 fn default() -> Self {
176 Self::new()
177 }
178}