feat: correct implementations for kebab, snake and title case

pull/12043/head
Nikita Revenco 2024-12-20 09:00:56 +00:00
parent f1cf46f022
commit ff8c1df71d
1 changed files with 51 additions and 45 deletions

View File

@ -88,60 +88,66 @@ pub fn to_pascal_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril)
}
}
pub fn to_snake_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {
let mut at_word_start = true;
pub fn to_title_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {
let mut capitalize_next = true;
let mut prev_is_lowercase = false;
for c in text {
// we don't count _ as a word char here so case conversions work well
if !c.is_alphanumeric() {
at_word_start = true;
continue;
}
if at_word_start {
at_word_start = false;
buf.push('_');
buf.push(c);
if c.is_alphanumeric() {
if capitalize_next || (prev_is_lowercase && c.is_uppercase()) {
buf.extend(c.to_uppercase());
capitalize_next = false;
} else {
buf.extend(c.to_lowercase());
}
prev_is_lowercase = c.is_lowercase();
} else {
buf.push(c)
capitalize_next = true;
prev_is_lowercase = false;
buf.push(' ');
}
}
*buf = buf.trim().into();
}
pub fn to_case_with_separator(
text: impl Iterator<Item = char>,
buf: &mut Tendril,
separator: char,
) {
let mut prev_is_lowercase = false; // Tracks if the previous character was lowercase
let mut prev_is_alphanumeric = false; // Tracks if the previous character was alphanumeric
for c in text {
if c.is_alphanumeric() {
if prev_is_lowercase && c.is_uppercase() {
buf.push(separator);
}
if !prev_is_alphanumeric && !buf.is_empty() {
buf.push(separator);
}
buf.push(c.to_ascii_lowercase());
prev_is_lowercase = c.is_lowercase();
prev_is_alphanumeric = true;
} else {
prev_is_lowercase = false;
prev_is_alphanumeric = false;
}
}
if buf.ends_with(separator) {
buf.pop();
}
}
pub fn to_kebab_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {
let mut at_word_start = false;
for c in text {
// we don't count _ as a word char here so case conversions work well
if !c.is_alphanumeric() {
at_word_start = true;
continue;
}
if at_word_start {
at_word_start = false;
buf.push('-');
buf.push(c);
} else {
buf.push(c)
}
}
to_case_with_separator(text, buf, '-');
}
pub fn to_title_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {
let mut at_word_start = true;
for (i, c) in text.enumerate() {
// we don't count _ as a word char here so case conversions work well
if !c.is_alphanumeric() {
at_word_start = true;
continue;
}
if at_word_start {
at_word_start = false;
if i != 0 {
buf.push(' ');
}
buf.extend(c.to_uppercase());
} else {
buf.push(c)
}
}
pub fn to_snake_case_with(text: impl Iterator<Item = char>, buf: &mut Tendril) {
to_case_with_separator(text, buf, '_');
}
pub fn to_camel_case_with(mut text: impl Iterator<Item = char>, buf: &mut Tendril) {