pub(crate) fn validate_name(name: &str, line: u32, kind: &str) -> Result<(), String> {
let mut chars = name.chars();
let Some(first) = chars.next() else {
return Err(if line == 0 {
format!("{kind} name is empty")
} else {
format!("line {line}: {kind} name is empty")
});
};
if !(first.is_ascii_alphabetic() || first == '_') {
return Err(if line == 0 {
format!("invalid {kind} name `{name}`")
} else {
format!("line {line}: invalid {kind} name `{name}`")
});
}
if chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_') {
Ok(())
} else if line == 0 {
Err(format!("invalid {kind} name `{name}`"))
} else {
Err(format!("line {line}: invalid {kind} name `{name}`"))
}
}