1use std::path::Path;
2
3use anyhow::Result;
4use dprint_core::configuration::resolve_new_line_kind;
5use dprint_core::formatting::PrintOptions;
6
7use crate::configuration::Configuration;
8use crate::generation;
9
10pub fn format_text(_path: &Path, text: &str, config: &Configuration) -> Result<Option<String>> {
11 let result = format_text_inner(text, config)?;
12 if result == text { Ok(None) } else { Ok(Some(result)) }
13}
14
15fn format_text_inner(text: &str, config: &Configuration) -> Result<String> {
16 let text = text.strip_prefix('\u{FEFF}').unwrap_or(text);
17 let tokens = generation::tokenize(text);
18 if has_ignore_file_comment(&tokens, &config.ignore_file_comment_text) {
19 return Ok(text.to_string());
20 }
21 let statements = generation::parse(&tokens, text);
22 if statements.is_empty() {
23 return Ok(String::new());
24 }
25 Ok(dprint_core::formatting::format(
26 || generation::generate(&statements, text, config),
27 PrintOptions {
28 indent_width: config.indent_width,
29 max_width: config.line_width,
30 use_tabs: config.use_tabs,
31 new_line_text: resolve_new_line_kind(text, config.new_line_kind),
32 },
33 ))
34}
35
36fn has_ignore_file_comment(tokens: &[generation::Token], directive: &str) -> bool {
39 for token in tokens {
40 match token.kind {
41 generation::TokenKind::Whitespace { .. } => {}
42 generation::TokenKind::LineComment | generation::TokenKind::BlockComment => {
43 if token.text.contains(directive) {
44 return true;
45 }
46 }
47 _ => return false,
48 }
49 }
50 false
51}