1mod comments;
15mod emit;
16
17#[cfg(test)]
18mod tests;
19
20use bock_lexer::Lexer;
21use bock_parser::Parser;
22use bock_source::SourceFile;
23
24pub use emit::Formatter;
25
26#[derive(Debug)]
28pub struct FormatResult {
29 pub output: String,
31 pub changed: bool,
33}
34
35#[must_use]
40pub fn format_source(source: &str, filename: &str) -> FormatResult {
41 let file = SourceFile::new(
42 bock_errors::FileId(0),
43 std::path::PathBuf::from(filename),
44 source.to_string(),
45 );
46 let mut lexer = Lexer::new(&file);
47 let tokens = lexer.tokenize();
48
49 if lexer.diagnostics().has_errors() {
51 return FormatResult {
52 output: source.to_string(),
53 changed: false,
54 };
55 }
56
57 let mut parser = Parser::new(tokens, &file);
58 let module = parser.parse_module();
59
60 if parser.diagnostics().has_errors() {
62 return FormatResult {
63 output: source.to_string(),
64 changed: false,
65 };
66 }
67
68 let comments = comments::extract_comments(source);
69 let mut formatter = Formatter::new(&comments, source);
70 formatter.format_module(&module);
71 let output = formatter.finish();
72
73 let changed = output != source;
74 FormatResult { output, changed }
75}