fn lowercase(s: &str) -> String {
s.to_lowercase()
}
fn uppercase(s: &str) -> String {
s.to_uppercase()
}
fn capitalize(s: &str) -> String {
let mut chars = s.chars();
match chars.next() {
Some(first) => first
.to_uppercase()
.chain(chars.map(|c| c.to_ascii_lowercase()))
.collect(),
None => String::new(),
}
}
fn capitalize_words(s: &str) -> String {
s.split_whitespace()
.map(capitalize)
.collect::<Vec<_>>()
.join(" ")
}
fn decapitalize(s: &str) -> String {
let mut chars = s.chars();
match chars.next() {
Some(first) => first.to_lowercase().chain(chars).collect(),
None => String::new(),
}
}
fn replace(s: &str, from: &str, to: &str) -> String {
s.replace(from, to)
}
fn strip_dashes(s: &str) -> String {
replace(s, "-", " ")
}
fn strip_underscores(s: &str) -> String {
replace(s, "_", " ")
}
fn strip_whitespace(s: &str) -> String {
replace(s, " ", "")
}
fn add_dashes(s: &str) -> String {
replace(s, " ", "-")
}
fn add_underscores(s: &str) -> String {
replace(s, " ", "_")
}
fn pipe(a: impl Fn(&str) -> String, b: impl Fn(&str) -> String) -> impl Fn(&str) -> String {
move |s: &str| b(&a(s))
}
fn strip(s: &str) -> String {
pipe(strip_underscores, strip_dashes)(s)
}
pub fn start_case(s: &str) -> String {
pipe(strip, capitalize_words)(s)
}
pub fn pascal_case(s: &str) -> String {
pipe(start_case, strip_whitespace)(s)
}
pub fn camel_case(s: &str) -> String {
pipe(pascal_case, decapitalize)(s)
}
pub fn kebab_case(s: &str) -> String {
pipe(lowercase, pipe(strip, add_dashes))(s)
}
pub fn snake_case(s: &str) -> String {
pipe(lowercase, pipe(strip, add_underscores))(s)
}
pub fn constant_case(s: &str) -> String {
pipe(uppercase, pipe(strip, add_underscores))(s)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_start_case() {
assert_eq!(start_case("hello world"), String::from("Hello World"));
assert_eq!(start_case("hello_world"), String::from("Hello World"));
assert_eq!(start_case("hello-world"), String::from("Hello World"));
assert_eq!(start_case("Hello World"), String::from("Hello World"));
}
#[test]
fn test_pascal_case() {
assert_eq!(pascal_case("hello world"), String::from("HelloWorld"));
assert_eq!(pascal_case("hello_world"), String::from("HelloWorld"));
assert_eq!(pascal_case("hello-world"), String::from("HelloWorld"));
assert_eq!(pascal_case("Hello World"), String::from("HelloWorld"));
}
#[test]
fn test_camel_case() {
assert_eq!(camel_case("hello world"), String::from("helloWorld"));
assert_eq!(camel_case("hello_world"), String::from("helloWorld"));
assert_eq!(camel_case("hello-world"), String::from("helloWorld"));
assert_eq!(camel_case("Hello World"), String::from("helloWorld"));
}
#[test]
fn test_kebab_case() {
assert_eq!(kebab_case("hello world"), String::from("hello-world"));
assert_eq!(kebab_case("hello_world"), String::from("hello-world"));
assert_eq!(kebab_case("hello-world"), String::from("hello-world"));
assert_eq!(kebab_case("Hello World"), String::from("hello-world"));
}
#[test]
fn test_snake_case() {
assert_eq!(snake_case("hello world"), String::from("hello_world"));
assert_eq!(snake_case("hello-world"), String::from("hello_world"));
assert_eq!(snake_case("hello_world"), String::from("hello_world"));
assert_eq!(snake_case("Hello World"), String::from("hello_world"));
}
#[test]
fn test_constant_case() {
assert_eq!(constant_case("hello world"), String::from("HELLO_WORLD"));
assert_eq!(constant_case("hello-world"), String::from("HELLO_WORLD"));
assert_eq!(constant_case("hello_world"), String::from("HELLO_WORLD"));
assert_eq!(constant_case("Hello World"), String::from("HELLO_WORLD"));
}
}