Why does to_ascii_lowercase return a String rather than a Cow<str>?
Asked Answered
S

1

7

str::to_ascii_lowercase returns a String. Why doesn't it return a Cow<str> just like to_string_lossy or String::from_utf8_lossy?

The same applies to str::to_ascii_uppercase.

Sheriff answered 17/8, 2018 at 11:30 Comment(0)
D
2

The reason why you might want to return a Cow<str> presumably is because the string may already be lower case. However, to detect this edge case might also introduce a performance degradation when the string is not already lower case, which intuitively seems like the most common scenario.

You can, of course, create your own function that wraps to_ascii_lowercase(), checks if it is already lower case, and return a Cow<str>:

fn my_to_ascii_lowercase<'a>(s: &'a str) -> Cow<'a, str> {
    let bytes = s.as_bytes();
    if !bytes.iter().any(u8::is_ascii_uppercase) {
        Cow::Borrowed(s)
    } else {
        Cow::Owned(s.to_ascii_lowercase())
    }
}
Dibbell answered 17/8, 2018 at 11:54 Comment(2)
This was my first thought, but you have to check the edge case anyway: While iterating over the string slice, you have to check every single character. For now, the String is allocated before and then it loops over every letter. It's changed when needed. You could just search for the first occurrence of a upper cased letter: str.chars().position(|c| !c.is_lowercase()). If nothing is found, you return Cow::Borrow, otherwise you start converting to lower case from this point.Sheriff
More or less thisSheriff

© 2022 - 2024 — McMap. All rights reserved.