use heck::{ToSnakeCase, ToUpperCamelCase};
pub(crate) fn sanitize_identifier(s: impl AsRef<str>) -> String {
let ident = s.as_ref();
match ident {
| "as" | "break" | "const" | "continue" | "else" | "enum" | "false"
| "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "match" | "mod" | "move" | "mut"
| "pub" | "ref" | "return" | "static" | "struct" | "trait" | "true"
| "type" | "unsafe" | "use" | "where" | "while"
| "dyn"
| "abstract" | "become" | "box" | "do" | "final" | "macro" | "override" | "priv" | "typeof"
| "unsized" | "virtual" | "yield"
| "async" | "await" | "try"
| "gen" => format!("r#{ident}"),
"_" | "super" | "self" | "Self" | "extern" | "crate" => format!("{ident}_"),
s if s.starts_with(|c: char| c.is_numeric()) => format!("_{ident}"),
_ => ident.to_string(),
}
}
pub(crate) fn to_snake(s: impl AsRef<str>) -> String {
sanitize_identifier(s.as_ref().to_snake_case())
}
pub(crate) fn to_upper_camel(s: impl AsRef<str>) -> String {
sanitize_identifier(s.as_ref().to_upper_camel_case())
}
pub(crate) fn strip_enum_prefix(prefix: &str, name: &str) -> String {
let stripped = name.strip_prefix(prefix).unwrap_or(name);
let stripped = if stripped.chars().next().map(char::is_uppercase).unwrap_or(false) {
stripped
} else {
name
};
sanitize_identifier(stripped)
}