use yog_ids::script_problem;
use super::Resolver;
use crate::ast::Name;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Case {
Pascal,
Camel,
Interface,
TypeParam,
Any,
}
const DISCARD: &str = "_";
const INTERFACE_MARK: char = 'I';
const TYPE_PARAM_MARK: char = 'T';
const SEPARATOR: char = '_';
impl Case {
fn fits(self, name: &str) -> bool {
let mut chars = name.chars();
let (Some(first), second) = (chars.next(), chars.next()) else {
return true;
};
if name.contains(SEPARATOR) && self != Case::Any {
return false;
}
match self {
Case::Pascal => first.is_uppercase(),
Case::Camel => first.is_lowercase(),
Case::Interface => first == INTERFACE_MARK && second.is_some_and(char::is_uppercase),
Case::TypeParam => first == TYPE_PARAM_MARK && second.is_none_or(char::is_uppercase),
Case::Any => true,
}
}
fn describe(self) -> &'static str {
match self {
Case::Pascal => "PascalCase (`ChargeLevel`)",
Case::Camel => "camelCase (`chargeLevel`)",
Case::Interface => "`I` and PascalCase (`IChargeable`)",
Case::TypeParam => "`T` or `T` and PascalCase (`TItem`)",
Case::Any => "any case",
}
}
}
impl Resolver<'_, '_> {
pub(super) fn check_case(&mut self, name: &Name, case: Case) {
if name.text == DISCARD || case.fits(&name.text) {
return;
}
self.report.warning(
script_problem::NAMING,
name.span,
format!("`{}` should be written in {}", name.text, case.describe()),
);
}
}