use heck::ToUpperCamelCase;
pub fn pascal(raw: &str) -> String {
raw.to_upper_camel_case()
}
pub fn type_name(raw: &str, suffix: &str) -> String {
let pascal = raw.to_upper_camel_case();
if pascal.ends_with(suffix) {
pascal
} else {
format!("{pascal}{suffix}")
}
}
pub fn exception_type_name(raw: &str) -> String {
let pascal = raw.to_upper_camel_case();
let stem = pascal.strip_suffix("Error").unwrap_or(&pascal);
type_name(stem, "Exception")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn type_name_avoids_screaming_and_doubling() {
assert_eq!(type_name("KEY_NOT_FOUND", "Error"), "KeyNotFoundError");
assert_eq!(
type_name("KEY_NOT_FOUND", "Exception"),
"KeyNotFoundException"
);
assert_eq!(type_name("AlreadyError", "Error"), "AlreadyError");
assert_eq!(type_name("invalid_input", "Error"), "InvalidInputError");
}
#[test]
fn exception_type_name_replaces_error_stem() {
assert_eq!(exception_type_name("KvError"), "KvException");
assert_eq!(exception_type_name("ContactsError"), "ContactsException");
assert_eq!(exception_type_name("Failure"), "FailureException");
assert_eq!(exception_type_name("KvException"), "KvException");
assert_eq!(exception_type_name("Error"), "Exception");
}
#[test]
fn pascal_is_suffix_free() {
assert_eq!(pascal("KEY_NOT_FOUND"), "KeyNotFound");
}
}