1 //! Syntax highlighting for format macro strings.
3 ast::{self, FormatSpecifier, HasFormatSpecifier},
4 AstNode, AstToken, TextRange,
7 use crate::{syntax_highlighting::highlights::Highlights, HlRange, HlTag, SymbolKind};
9 pub(super) fn highlight_format_string(
10 stack: &mut Highlights,
14 if is_format_string(string).is_none() {
18 string.lex_format_specifier(|piece_range, kind| {
19 if let Some(highlight) = highlight_format_specifier(kind) {
21 range: piece_range + range.start(),
22 highlight: highlight.into(),
29 fn is_format_string(string: &ast::String) -> Option<()> {
30 let parent = string.syntax().parent();
32 let name = parent.parent().and_then(ast::MacroCall::cast)?.path()?.segment()?.name_ref()?;
33 if !matches!(name.text(), "format_args" | "format_args_nl") {
37 let first_literal = parent
38 .children_with_tokens()
39 .filter_map(|it| it.as_token().cloned().and_then(ast::String::cast))
41 if &first_literal != string {
48 fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HlTag> {
51 | FormatSpecifier::Close
52 | FormatSpecifier::Colon
53 | FormatSpecifier::Fill
54 | FormatSpecifier::Align
55 | FormatSpecifier::Sign
56 | FormatSpecifier::NumberSign
57 | FormatSpecifier::DollarSign
58 | FormatSpecifier::Dot
59 | FormatSpecifier::Asterisk
60 | FormatSpecifier::QuestionMark => HlTag::FormatSpecifier,
62 FormatSpecifier::Integer | FormatSpecifier::Zero => HlTag::NumericLiteral,
64 FormatSpecifier::Identifier => HlTag::Symbol(SymbolKind::Local),