1 //! Syntax highlighting for format macro strings.
2 use ide_db::SymbolKind;
4 ast::{self, FormatSpecifier, HasFormatSpecifier},
5 AstNode, AstToken, TextRange,
8 use crate::{syntax_highlighting::highlights::Highlights, HlRange, HlTag};
10 pub(super) fn highlight_format_string(
11 stack: &mut Highlights,
15 if is_format_string(string).is_none() {
19 string.lex_format_specifier(|piece_range, kind| {
20 if let Some(highlight) = highlight_format_specifier(kind) {
22 range: piece_range + range.start(),
23 highlight: highlight.into(),
30 fn is_format_string(string: &ast::String) -> Option<()> {
31 let parent = string.syntax().parent()?;
33 let name = parent.parent().and_then(ast::MacroCall::cast)?.path()?.segment()?.name_ref()?;
34 if !matches!(name.text(), "format_args" | "format_args_nl") {
38 let first_literal = parent
39 .children_with_tokens()
40 .filter_map(|it| it.as_token().cloned().and_then(ast::String::cast))
42 if &first_literal != string {
49 fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HlTag> {
52 | FormatSpecifier::Close
53 | FormatSpecifier::Colon
54 | FormatSpecifier::Fill
55 | FormatSpecifier::Align
56 | FormatSpecifier::Sign
57 | FormatSpecifier::NumberSign
58 | FormatSpecifier::DollarSign
59 | FormatSpecifier::Dot
60 | FormatSpecifier::Asterisk
61 | FormatSpecifier::QuestionMark => HlTag::FormatSpecifier,
63 FormatSpecifier::Integer | FormatSpecifier::Zero => HlTag::NumericLiteral,
65 FormatSpecifier::Identifier => HlTag::Symbol(SymbolKind::Local),