1pub mod reader;
2pub mod classifier;
3pub mod scope;
4pub mod whitespace;
5pub mod case_norm;
6pub mod keyword_norm;
7pub mod formatter;
8pub mod config;
9pub mod align;
10pub mod unicode;
11pub mod cli;
12pub mod lsp;
13
14pub use config::Config;
15
16pub fn match_dot_token(bytes: &[u8], pos: usize) -> Option<(usize, bool)> {
20 if bytes[pos] != b'.' {
21 return None;
22 }
23 let len = bytes.len();
24 let mut end = pos + 1;
25 while end < len && bytes[end].is_ascii_alphabetic() {
26 end += 1;
27 }
28 if end >= len || bytes[end] != b'.' {
29 return None;
30 }
31 end += 1;
32
33 let word: String = bytes[pos + 1..end - 1]
34 .iter()
35 .map(|&b| (b as char).to_ascii_lowercase())
36 .collect();
37
38 match word.as_str() {
39 "eq" | "ne" | "lt" | "le" | "gt" | "ge" | "and" | "or" | "not" | "eqv" | "neqv" => {
40 Some((end, true)) }
42 "true" | "false" => {
43 Some((end, false)) }
45 _ => None,
46 }
47}
48
49pub fn format_string(source: &str) -> String {
51 formatter::format(source)
52}
53
54pub fn format_string_with_config(source: &str, config: &Config) -> String {
56 formatter::format_with_config(source, config, None)
57}
58
59pub fn format_range(source: &str, start: usize, end: usize) -> String {
61 formatter::format_with_range(source, Some((start, end)))
62}
63
64pub fn format_file(path: &std::path::Path) -> std::io::Result<bool> {
66 let source = std::fs::read_to_string(path)?;
67 let formatted = format_string(&source);
68 if formatted == source {
69 return Ok(false);
70 }
71 std::fs::write(path, &formatted)?;
72 Ok(true)
73}