1#![doc = include_str!("readme.md")]
2
3use crate::{
4 ast::{RustRoot, *},
5 lexer::RustTokenType,
6};
7
8pub struct RustFormatter {
25 indent_level: usize,
27 indent_str: String,
29 max_line_length: usize,
31}
32
33impl RustFormatter {
34 pub fn new() -> Self {
48 Self {
49 indent_level: 0,
50 indent_str: " ".to_string(), max_line_length: 100,
52 }
53 }
54
55 pub fn with_config(indent_str: String, max_line_length: usize) -> Self {
66 Self { indent_level: 0, indent_str, max_line_length }
67 }
68
69 pub fn format(&self, source: &str) -> String {
88 self.basic_format(source)
91 }
92
93 pub fn format_ast(&self, root: &RustRoot) -> String {
103 let mut result = String::new();
104
105 for (i, item) in root.items.iter().enumerate() {
106 if i > 0 {
107 result.push_str("\n\n");
108 }
109 result.push_str(&self.format_item(item));
110 }
111
112 result
113 }
114
115 fn format_item(&self, item: &Item) -> String {
117 match item {
118 Item::Function(func) => self.format_function(func),
119 Item::Struct(struct_def) => self.format_struct(struct_def),
120 Item::Enum(enum_def) => self.format_enum(enum_def),
121 Item::Trait(trait_def) => self.format_trait(trait_def),
122 Item::Impl(impl_block) => self.format_impl(impl_block),
123 Item::Module(module) => self.format_module(module),
124 Item::Use(use_item) => self.format_use(use_item),
125 Item::Const(const_item) => self.format_const(const_item),
126 Item::Static(static_item) => self.format_static(static_item),
127 Item::TypeAlias(type_alias) => self.format_type_alias(type_alias),
128 Item::ExternBlock(extern_block) => self.format_extern_block(extern_block),
129 }
130 }
131
132 fn format_function(&self, func: &Function) -> String {
134 let mut result = String::new();
135
136 if func.is_async {
138 result.push_str("async ");
139 }
140 if func.is_unsafe {
141 result.push_str("unsafe ");
142 }
143
144 result.push_str("fn ");
145 result.push_str(&func.name.name);
146
147 result.push('(');
149 for (i, param) in func.params.iter().enumerate() {
150 if i > 0 {
151 result.push_str(", ");
152 }
153 result.push_str(&self.format_param(param));
154 }
155 result.push(')');
156
157 if let Some(return_type) = &func.return_type {
159 result.push_str(" -> ");
160 result.push_str(&self.format_type(return_type));
161 }
162
163 result.push(' ');
165 result.push_str(&self.format_block(&func.body));
166
167 result
168 }
169
170 fn format_param(&self, param: &Param) -> String {
172 let mut result = String::new();
173 if param.is_mut {
174 result.push_str("mut ");
175 }
176 result.push_str(¶m.name.name);
177 result.push_str(": ");
178 result.push_str(&self.format_type(¶m.ty));
179 result
180 }
181
182 fn format_block(&self, block: &Block) -> String {
184 let mut result = String::new();
185 result.push_str("{\n");
186
187 let mut formatter = self.clone();
189 formatter.indent_level += 1;
190
191 for stmt in &block.statements {
193 result.push_str(&formatter.get_indent());
194 result.push_str(&formatter.format_statement(stmt));
195 result.push('\n');
196 }
197
198 result.push_str(&self.get_indent());
199 result.push('}');
200 result
201 }
202
203 fn format_statement(&self, stmt: &Statement) -> String {
205 match stmt {
206 Statement::Let { name, ty, expr, mutable, .. } => {
207 let mut result = String::new();
208 result.push_str("let ");
209 if *mutable {
210 result.push_str("mut ");
211 }
212 result.push_str(&name.name);
213
214 if let Some(ty) = ty {
215 result.push_str(": ");
216 result.push_str(&self.format_type(ty));
217 }
218
219 if let Some(expr) = expr {
220 result.push_str(" = ");
221 result.push_str(&self.format_expr(expr));
222 }
223
224 result.push(';');
225 result
226 }
227 Statement::ExprStmt { expr, semi, .. } => {
228 let mut result = self.format_expr(expr);
229 if *semi {
230 result.push(';');
231 }
232 result
233 }
234 Statement::Return { expr, .. } => {
235 let mut result = String::from("return");
236 if let Some(expr) = expr {
237 result.push(' ');
238 result.push_str(&self.format_expr(expr));
239 }
240 result.push(';');
241 result
242 }
243 Statement::Break { expr, .. } => {
244 let mut result = String::from("break");
245 if let Some(expr) = expr {
246 result.push(' ');
247 result.push_str(&self.format_expr(expr));
248 }
249 result.push(';');
250 result
251 }
252 Statement::Continue { .. } => String::from("continue;"),
253 Statement::Item(item) => self.format_item(item),
254 }
255 }
256
257 fn format_expr(&self, expr: &Expr) -> String {
259 match expr {
260 Expr::Literal { value, .. } => value.clone(),
261 Expr::Bool { value, .. } => value.to_string(),
262 Expr::Ident(ident) => ident.name.clone(),
263 Expr::Binary { left, op, right, .. } => {
264 format!("{} {} {}", self.format_expr(left), self.format_syntax_kind(op), self.format_expr(right))
265 }
266 Expr::Unary { op, expr, .. } => {
267 format!("{}{}", self.format_syntax_kind(op), self.format_expr(expr))
268 }
269 Expr::Call { callee, args, .. } => {
270 let mut result = self.format_expr(callee);
271 result.push('(');
272 for (i, arg) in args.iter().enumerate() {
273 if i > 0 {
274 result.push_str(", ");
275 }
276 result.push_str(&self.format_expr(arg));
277 }
278 result.push(')');
279 result
280 }
281 Expr::Field { receiver, field, .. } => {
282 format!("{}.{}", self.format_expr(receiver), field.name)
283 }
284 Expr::Index { receiver, index, .. } => {
285 format!("{}[{}]", self.format_expr(receiver), self.format_expr(index))
286 }
287 Expr::Paren { expr, .. } => {
288 format!("({})", self.format_expr(expr))
289 }
290 Expr::Block(block) => self.format_block(block),
291 _ => "/* unsupported expression */".to_string(),
292 }
293 }
294
295 fn _format_literal_expr(&self, expr: &Expr) -> String {
297 match expr {
298 Expr::Literal { value, .. } => value.clone(),
299 Expr::Bool { value, .. } => value.to_string(),
300 _ => "".to_string(), }
302 }
303
304 fn format_syntax_kind(&self, kind: &RustTokenType) -> String {
306 match kind {
307 RustTokenType::Plus => "+".to_string(),
308 RustTokenType::Minus => "-".to_string(),
309 RustTokenType::Star => "*".to_string(),
310 RustTokenType::Slash => "/".to_string(),
311 RustTokenType::Percent => "%".to_string(),
312 RustTokenType::EqEq => "==".to_string(),
313 RustTokenType::Ne => "!=".to_string(),
314 RustTokenType::Lt => "<".to_string(),
315 RustTokenType::Le => "<=".to_string(),
316 RustTokenType::Gt => ">".to_string(),
317 RustTokenType::Ge => ">=".to_string(),
318 RustTokenType::AndAnd => "&&".to_string(),
319 RustTokenType::OrOr => "||".to_string(),
320 RustTokenType::Bang => "!".to_string(),
321 RustTokenType::Ampersand => "&".to_string(),
322 _ => "/* unsupported operator */".to_string(),
323 }
324 }
325
326 fn get_indent(&self) -> String {
328 self.indent_str.repeat(self.indent_level)
329 }
330
331 fn basic_format(&self, source: &str) -> String {
333 source.replace("{", " {\n").replace("}", "\n}").replace(";", ";\n").lines().map(|line| line.trim()).filter(|line| !line.is_empty()).collect::<Vec<_>>().join("\n")
335 }
336
337 fn format_struct(&self, _struct_def: &Struct) -> String {
339 "/* struct formatting not implemented */".to_string()
340 }
341
342 fn format_enum(&self, _enum_def: &Enum) -> String {
343 "/* enum formatting not implemented */".to_string()
344 }
345
346 fn format_trait(&self, _trait_def: &Trait) -> String {
347 "/* trait formatting not implemented */".to_string()
348 }
349
350 fn format_impl(&self, _impl_block: &Impl) -> String {
351 "/* impl formatting not implemented */".to_string()
352 }
353
354 fn format_module(&self, _module: &Module) -> String {
355 "/* module formatting not implemented */".to_string()
356 }
357
358 fn format_use(&self, use_item: &UseItem) -> String {
359 format!("use {};", use_item.path)
360 }
361
362 fn format_const(&self, const_item: &Const) -> String {
363 format!("const {}: {} = {};", const_item.name.name, self.format_type(&const_item.ty), self.format_expr(&const_item.expr))
364 }
365
366 fn format_static(&self, static_item: &Static) -> String {
367 let mut_keyword = if static_item.mutable { "mut " } else { "" };
368 format!("static {}{}: {} = {};", mut_keyword, static_item.name.name, self.format_type(&static_item.ty), self.format_expr(&static_item.expr))
369 }
370
371 fn format_type_alias(&self, type_alias: &TypeAlias) -> String {
372 format!("type {} = {};", type_alias.name.name, self.format_type(&type_alias.ty))
373 }
374
375 fn _format_macro_def(&self, _macro_def: &str) -> String {
376 "/* macro definition formatting not implemented */".to_string()
377 }
378
379 fn format_extern_block(&self, _extern_block: &ExternBlock) -> String {
380 "extern {}".to_string()
382 }
383
384 fn _format_generics(&self, _generics: &str) -> String {
385 "/* generics formatting not implemented */".to_string()
386 }
387
388 fn format_type(&self, _ty: &Type) -> String {
389 "/* type formatting not implemented */".to_string()
390 }
391
392 fn _format_pattern(&self, _pattern: &Pattern) -> String {
393 "/* pattern formatting not implemented */".to_string()
394 }
395}
396
397impl Clone for RustFormatter {
398 fn clone(&self) -> Self {
399 Self { indent_level: self.indent_level, indent_str: self.indent_str.clone(), max_line_length: self.max_line_length }
400 }
401}
402
403impl Default for RustFormatter {
404 fn default() -> Self {
405 Self::new()
406 }
407}