use std::collections::{BTreeSet, HashSet};
use syn::visit::Visit;
pub(crate) fn assert_banned_idents<'a>(
file: &syn::File,
idents: impl IntoIterator<Item = &'a str>,
) {
let found = find_idents(file, idents);
if !found.is_empty() {
let found = found.into_iter().collect::<Vec<_>>();
panic!("banned identifiers found in file: {}", found.join(", "));
}
}
pub(crate) fn find_idents<'a>(
file: &syn::File,
idents: impl IntoIterator<Item = &'a str>,
) -> BTreeSet<String> {
let idents: HashSet<_> = idents.into_iter().collect();
let mut visitor =
BanIdentsVisitor { idents: &idents, found: BTreeSet::new() };
visitor.visit_file(file);
visitor.found
}
struct BanIdentsVisitor<'a> {
idents: &'a HashSet<&'a str>,
found: BTreeSet<String>,
}
impl<'a> syn::visit::Visit<'a> for BanIdentsVisitor<'a> {
fn visit_ident(&mut self, ident: &'a syn::Ident) {
let ident = ident.to_string();
if self.idents.contains(&ident.as_str()) {
self.found.insert(ident);
}
}
}