use std::collections::BTreeSet;
use crate::macro_path::{matches_any, merge_with_builtins, parse_path, parse_path_list};
const CONFIG_KEY: &str = "perfectionist::macro_trailing_comma";
const BUILTIN_NAME_BASED: &[&str] = &[
"vec",
"format",
"format_args",
"print",
"println",
"eprint",
"eprintln",
"write",
"writeln",
"panic",
"unimplemented",
"todo",
"unreachable",
"assert",
"assert_eq",
"assert_ne",
"debug_assert",
"debug_assert_eq",
"debug_assert_ne",
"matches",
"dbg",
"concat",
"env",
"option_env",
"assert_str_eq",
"hashmap",
"btreemap",
"hashset",
"btreeset",
"convert_args",
"log",
"error",
"warn",
"info",
"debug",
"trace",
"event",
"span",
"anyhow",
"bail",
"ensure",
];
#[derive(Debug, Default, serde::Deserialize)]
#[serde(default, deny_unknown_fields, rename_all = "snake_case")]
struct Config {
extra_macros: Vec<String>,
ignore: Vec<String>,
}
pub(super) struct MacroTrailingComma {
name_based: BTreeSet<Vec<String>>,
ignore: BTreeSet<Vec<String>>,
}
impl MacroTrailingComma {
pub(super) fn new() -> Self {
let config: Config = dylint_linting::config_or_default(CONFIG_KEY);
let extra_macros: BTreeSet<Vec<String>> = config
.extra_macros
.iter()
.map(|entry| parse_path(entry))
.filter(|parsed| !parsed.is_empty())
.collect();
let name_based = merge_with_builtins(BUILTIN_NAME_BASED, &extra_macros);
let ignore = parse_path_list(&config.ignore);
Self { name_based, ignore }
}
pub(super) fn should_check_path(&self, path: &rustc_ast::Path) -> bool {
!matches_any(path, &self.ignore) && matches_any(path, &self.name_based)
}
}