pub use vize_carton::{camelize, capitalize, hyphenate, is_simple_identifier, String};
use once_cell::sync::Lazy;
use rustc_hash::FxHashMap;
use std::sync::RwLock;
use vize_carton::CompactString;
static PASCAL_CASE_CACHE: Lazy<RwLock<FxHashMap<CompactString, CompactString>>> =
Lazy::new(|| RwLock::new(FxHashMap::default()));
pub fn to_pascal_case(s: &str) -> CompactString {
if s.is_empty() {
return CompactString::default();
}
{
let cache = PASCAL_CASE_CACHE.read().unwrap();
if let Some(cached) = cache.get(s) {
return cached.clone();
}
}
let result = to_pascal_case_uncached(s);
{
let mut cache = PASCAL_CASE_CACHE.write().unwrap();
cache.insert(CompactString::new(s), result.clone());
}
result
}
fn to_pascal_case_uncached(s: &str) -> CompactString {
let mut result = String::with_capacity(s.len());
let mut capitalize_next = true;
for c in s.chars() {
if c == '-' || c == '_' {
capitalize_next = true;
} else if capitalize_next {
result.push(c.to_ascii_uppercase());
capitalize_next = false;
} else {
result.push(c);
}
}
CompactString::new(&result)
}
#[inline]
pub fn is_camel_case(s: &str) -> bool {
if s.is_empty() {
return false;
}
let mut chars = s.chars();
let first = chars.next().unwrap();
if !first.is_ascii_lowercase() {
return false;
}
let mut has_uppercase = false;
for c in chars {
if c == '-' || c == '_' {
return false;
}
if c.is_ascii_uppercase() {
has_uppercase = true;
}
}
has_uppercase
}
#[inline]
pub fn is_camel_case_loose(s: &str) -> bool {
if s.is_empty() {
return false;
}
let first = s.chars().next().unwrap();
if !first.is_ascii_lowercase() {
return false;
}
!s.contains('-') && !s.contains('_')
}
#[inline]
pub fn is_pascal_case(s: &str) -> bool {
if s.is_empty() {
return false;
}
let first = s.chars().next().unwrap();
if !first.is_ascii_uppercase() {
return false;
}
!s.contains('-') && !s.contains('_')
}
#[inline]
pub fn is_kebab_case(s: &str) -> bool {
if s.is_empty() {
return false;
}
if !s.contains('-') {
return false;
}
s.chars().all(|c| !c.is_ascii_uppercase())
}
#[inline]
pub fn is_kebab_case_loose(s: &str) -> bool {
if s.is_empty() {
return false;
}
s.chars().all(|c| !c.is_ascii_uppercase())
}
#[inline]
pub fn names_match(a: &str, b: &str) -> bool {
if a == b {
return true;
}
camelize(a) == camelize(b)
}
#[cfg(test)]
mod tests {
use super::{
is_camel_case, is_camel_case_loose, is_kebab_case, is_kebab_case_loose, is_pascal_case,
names_match, to_pascal_case,
};
#[test]
fn test_to_pascal_case() {
assert_eq!(to_pascal_case("my-component").as_str(), "MyComponent");
assert_eq!(to_pascal_case("myComponent").as_str(), "MyComponent");
assert_eq!(to_pascal_case("MyComponent").as_str(), "MyComponent");
assert_eq!(to_pascal_case("foo-bar-baz").as_str(), "FooBarBaz");
assert_eq!(to_pascal_case("foo_bar").as_str(), "FooBar");
assert_eq!(to_pascal_case("").as_str(), "");
}
#[test]
fn test_is_camel_case() {
assert!(is_camel_case("myComponent"));
assert!(is_camel_case("fooBar"));
assert!(is_camel_case("fooBarBaz"));
assert!(!is_camel_case("MyComponent"));
assert!(!is_camel_case("my-component"));
assert!(!is_camel_case("foo"));
assert!(!is_camel_case(""));
}
#[test]
fn test_is_camel_case_loose() {
assert!(is_camel_case_loose("myComponent"));
assert!(is_camel_case_loose("foo"));
assert!(!is_camel_case_loose("MyComponent"));
assert!(!is_camel_case_loose("my-component"));
}
#[test]
fn test_is_pascal_case() {
assert!(is_pascal_case("MyComponent"));
assert!(is_pascal_case("FooBar"));
assert!(is_pascal_case("Foo"));
assert!(!is_pascal_case("myComponent"));
assert!(!is_pascal_case("my-component"));
assert!(!is_pascal_case(""));
}
#[test]
fn test_is_kebab_case() {
assert!(is_kebab_case("my-component"));
assert!(is_kebab_case("foo-bar-baz"));
assert!(!is_kebab_case("myComponent"));
assert!(!is_kebab_case("MyComponent"));
assert!(!is_kebab_case("foo"));
assert!(!is_kebab_case(""));
}
#[test]
fn test_is_kebab_case_loose() {
assert!(is_kebab_case_loose("my-component"));
assert!(is_kebab_case_loose("foo"));
assert!(!is_kebab_case_loose("myComponent"));
assert!(!is_kebab_case_loose("MyComponent"));
}
#[test]
fn test_names_match() {
assert!(names_match("my-prop", "myProp"));
assert!(names_match("myProp", "my-prop"));
assert!(names_match("foo", "foo"));
assert!(names_match("foo-bar", "fooBar"));
assert!(!names_match("myProp", "otherProp"));
}
}