use std::str::FromStr;
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum EnumTransformation {
Uppercase,
Lowercase,
Snakecase,
Camelcase,
Pascalcase,
Kebabcase,
Screamingkebabcase,
Screamingsnakecase,
}
impl EnumTransformation {
pub fn apply(&self, value: &str) -> String {
use heck::{
ToKebabCase, ToLowerCamelCase, ToPascalCase, ToShoutyKebabCase, ToShoutySnakeCase,
ToSnakeCase,
};
match self {
Self::Uppercase => value.to_uppercase(),
Self::Lowercase => value.to_lowercase(),
Self::Snakecase => value.to_snake_case(),
Self::Camelcase => value.to_lower_camel_case(),
Self::Pascalcase => value.to_pascal_case(),
Self::Kebabcase => value.to_kebab_case(),
Self::Screamingkebabcase => value.to_shouty_kebab_case(),
Self::Screamingsnakecase => value.to_shouty_snake_case(),
}
}
}
impl FromStr for EnumTransformation {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_from(s)
}
}
impl TryFrom<String> for EnumTransformation {
type Error = String;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::try_from(value.as_str())
}
}
impl TryFrom<&str> for EnumTransformation {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let normalized = value
.replace([' ', '-', '_'], "")
.to_lowercase()
.trim_end_matches("case")
.to_string();
Ok(match normalized.as_str() {
"upper" => Self::Uppercase,
"lower" => Self::Lowercase,
"snake" => Self::Snakecase,
"camel" => Self::Camelcase,
"pascal" => Self::Pascalcase,
"kebab" => Self::Kebabcase,
"screamingkebab" => Self::Screamingkebabcase,
"screamingsnake" => Self::Screamingsnakecase,
_ => return Err(format!("Unknown transformation: {}", value)),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_snake_case() {
let helper = EnumTransformation::Snakecase;
assert_eq!(helper.apply("hello world"), "hello_world");
assert_eq!(helper.apply("helloWorld"), "hello_world");
assert_eq!(helper.apply("HelloWorld"), "hello_world");
assert_eq!(helper.apply("hello_world"), "hello_world");
}
#[test]
fn test_to_camel_case() {
let helper = EnumTransformation::Camelcase;
assert_eq!(helper.apply("hello world"), "helloWorld");
assert_eq!(helper.apply("hello_world"), "helloWorld");
assert_eq!(helper.apply("helloWorld"), "helloWorld");
assert_eq!(helper.apply("HelloWorld"), "helloWorld");
}
#[test]
fn test_to_pascal_case() {
let helper = EnumTransformation::Pascalcase;
assert_eq!(helper.apply("hello world"), "HelloWorld");
assert_eq!(helper.apply("hello_world"), "HelloWorld");
assert_eq!(helper.apply("helloWorld"), "HelloWorld");
assert_eq!(helper.apply("HelloWorld"), "HelloWorld");
}
#[test]
fn test_to_uppercase() {
let helper = EnumTransformation::Uppercase;
assert_eq!(helper.apply("hello world"), "HELLO WORLD");
assert_eq!(helper.apply("hello_world"), "HELLO_WORLD");
assert_eq!(helper.apply("helloWorld"), "HELLOWORLD");
assert_eq!(helper.apply("HelloWorld"), "HELLOWORLD");
}
#[test]
fn test_to_lowercase() {
let helper = EnumTransformation::Lowercase;
assert_eq!(helper.apply("hello world"), "hello world");
assert_eq!(helper.apply("hello_world"), "hello_world");
assert_eq!(helper.apply("helloWorld"), "helloworld");
assert_eq!(helper.apply("HelloWorld"), "helloworld");
}
#[test]
fn parse_aliases() {
assert_eq!(
EnumTransformation::try_from("camel").unwrap(),
EnumTransformation::Camelcase
);
assert_eq!(
EnumTransformation::try_from("pascal").unwrap(),
EnumTransformation::Pascalcase
);
assert_eq!(
EnumTransformation::try_from("snake").unwrap(),
EnumTransformation::Snakecase
);
assert_eq!(
EnumTransformation::try_from("upper").unwrap(),
EnumTransformation::Uppercase
);
assert_eq!(
EnumTransformation::try_from("lower").unwrap(),
EnumTransformation::Lowercase
);
}
#[test]
fn test_to_kebab_case() {
let helper = EnumTransformation::Kebabcase;
assert_eq!(helper.apply("HelloWorld"), "hello-world");
assert_eq!(helper.apply("helloWorld"), "hello-world");
}
#[test]
fn test_to_screaming_kebab_case() {
let helper = EnumTransformation::Screamingkebabcase;
assert_eq!(helper.apply("HelloWorld"), "HELLO-WORLD");
assert_eq!(helper.apply("helloWorld"), "HELLO-WORLD");
}
#[test]
fn test_to_screaming_snake_case() {
let helper = EnumTransformation::Screamingsnakecase;
assert_eq!(helper.apply("HelloWorld"), "HELLO_WORLD");
assert_eq!(helper.apply("helloWorld"), "HELLO_WORLD");
}
#[test]
fn parse_new_aliases() {
assert_eq!(
EnumTransformation::try_from("kebab").unwrap(),
EnumTransformation::Kebabcase
);
assert_eq!(
EnumTransformation::try_from("screamingkebab").unwrap(),
EnumTransformation::Screamingkebabcase
);
assert_eq!(
EnumTransformation::try_from("screamingsnake").unwrap(),
EnumTransformation::Screamingsnakecase
);
}
}