pub mod ast_visitor_base;
pub mod type_inference_visitor;
pub use ast_visitor_base::AstVisitorBase;
pub use type_inference_visitor::TypeInferenceVisitor;
pub trait IdentifierValidator {
fn is_valid_identifier(name: &str) -> bool {
if name.is_empty() {
return false;
}
let mut chars = name.chars();
match chars.next() {
Some(c) if c.is_ascii_alphabetic() || c == '_' => {},
_ => return false,
}
chars.all(|c| c.is_ascii_alphanumeric() || c == '_')
}
}
pub trait DuplicateChecker {
fn has_duplicates_ci(items: &[impl AsRef<str>]) -> bool {
use std::collections::HashSet;
let mut seen = HashSet::with_capacity(items.len());
for item in items {
let lower = item.as_ref().to_lowercase();
if !seen.insert(lower) {
return true;
}
}
false
}
fn find_duplicates_ci(items: &[impl AsRef<str>]) -> Vec<String> {
use std::collections::HashMap;
let mut counts: HashMap<String, usize> = HashMap::new();
for item in items {
let lower = item.as_ref().to_lowercase();
*counts.entry(lower).or_insert(0) += 1;
}
counts.into_iter()
.filter(|(_, count)| *count > 1)
.map(|(name, _)| name)
.collect()
}
}