use crate::error::{compile_error, Result};
use heck::{
ToKebabCase, ToLowerCamelCase, ToPascalCase, ToShoutyKebabCase, ToShoutySnakeCase, ToSnakeCase,
};
#[derive(Copy, Clone, Debug)]
pub(crate) enum RenameRule {
LowerCase,
UpperCase,
PascalCase,
CamelCase,
SnakeCase,
ScreamingSnakeCase,
KebabCase,
ScreamingKebabCase,
Identity,
}
impl RenameRule {
pub fn apply(self, input: &str) -> String {
match self {
Self::LowerCase => input.to_lowercase(),
Self::UpperCase => input.to_uppercase(),
Self::PascalCase => input.to_pascal_case(),
Self::CamelCase => input.to_lower_camel_case(),
Self::SnakeCase => input.to_snake_case(),
Self::ScreamingSnakeCase => input.to_shouty_snake_case(),
Self::KebabCase => input.to_kebab_case(),
Self::ScreamingKebabCase => input.to_shouty_kebab_case(),
Self::Identity => input.to_owned(),
}
}
pub fn parse(rule: &str) -> Result<Self> {
match rule {
"lowercase" => Ok(Self::LowerCase),
"UPPERCASE" => Ok(Self::UpperCase),
"PascalCase" => Ok(Self::PascalCase),
"camelCase" => Ok(Self::CamelCase),
"snake_case" => Ok(Self::SnakeCase),
"SCREAMING_SNAKE_CASE" => Ok(Self::ScreamingSnakeCase),
"kebab-case" => Ok(Self::KebabCase),
"SCREAMING-KEBAB-CASE" => Ok(Self::ScreamingKebabCase),
"identity" => Ok(Self::Identity),
invalid => Err(compile_error(format!(
"invalid rename rule `{invalid}` (supported: `lowercase`, `UPPERCASE`, \
`PascalCase`, `camelCase`, `snake_case`, `SCREAMING_SNAKE_CASE`, \
`kebab-case`, `SCREAMING-KEBAB-CASE`, `identity`)"
))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn lowercase_rule() {
assert_eq!(RenameRule::LowerCase.apply("HelloWorld"), "helloworld");
assert_eq!(RenameRule::LowerCase.apply("Help"), "help");
}
#[test]
fn uppercase_rule() {
assert_eq!(RenameRule::UpperCase.apply("Help"), "HELP");
}
#[test]
fn snake_case_rule() {
assert_eq!(RenameRule::SnakeCase.apply("GetHelp"), "get_help");
}
#[test]
fn identity_rule() {
assert_eq!(RenameRule::Identity.apply("Help"), "Help");
}
#[test]
fn parse_invalid_rule() {
assert!(RenameRule::parse("nope").is_err());
}
#[test]
fn parse_valid_rules() {
assert!(RenameRule::parse("lowercase").is_ok());
assert!(RenameRule::parse("UPPERCASE").is_ok());
assert!(RenameRule::parse("PascalCase").is_ok());
assert!(RenameRule::parse("camelCase").is_ok());
assert!(RenameRule::parse("snake_case").is_ok());
assert!(RenameRule::parse("SCREAMING_SNAKE_CASE").is_ok());
assert!(RenameRule::parse("kebab-case").is_ok());
assert!(RenameRule::parse("SCREAMING-KEBAB-CASE").is_ok());
assert!(RenameRule::parse("identity").is_ok());
}
}