str_utils/
to_lowercase.rs

1use alloc::borrow::Cow;
2
3use crate::{IsAsciiLowercased, IsLowercased};
4
5/// To extend `str` and `Cow<str>` to have `to_lowercase_cow` and `to_ascii_lowercase_cow` methods.
6pub trait ToLowercase<'a> {
7    /// Converts the string to its lowercase form (Unicode-aware), returning a `Cow<str>` to avoid allocation when possible.
8    fn to_lowercase_cow(self) -> Cow<'a, str>;
9
10    /// Converts the string to its ASCII lowercase form, returning a `Cow<str>` to avoid allocation when possible.
11    fn to_ascii_lowercase_cow(self) -> Cow<'a, str>;
12}
13
14impl<'a> ToLowercase<'a> for &'a str {
15    #[inline]
16    fn to_lowercase_cow(self) -> Cow<'a, str> {
17        if self.is_lowercased() {
18            Cow::Borrowed(self)
19        } else {
20            Cow::Owned(self.to_lowercase())
21        }
22    }
23
24    #[inline]
25    fn to_ascii_lowercase_cow(self) -> Cow<'a, str> {
26        if self.is_ascii_lowercased() {
27            Cow::Borrowed(self)
28        } else {
29            Cow::Owned(self.to_ascii_lowercase())
30        }
31    }
32}
33
34impl<'a> ToLowercase<'a> for Cow<'a, str> {
35    #[inline]
36    fn to_lowercase_cow(self) -> Cow<'a, str> {
37        match self {
38            Cow::Borrowed(s) => s.to_lowercase_cow(),
39            Cow::Owned(s) => {
40                match s.to_lowercase_cow() {
41                    Cow::Borrowed(_) => {
42                        // it changes nothing
43                        // if there were any characters that needed to be lowercased, it had to be `Cow::Owned`
44                        Cow::Owned(s)
45                    },
46                    Cow::Owned(s) => Cow::Owned(s),
47                }
48            },
49        }
50    }
51
52    #[inline]
53    fn to_ascii_lowercase_cow(self) -> Cow<'a, str> {
54        match self {
55            Cow::Borrowed(s) => s.to_ascii_lowercase_cow(),
56            Cow::Owned(s) => {
57                match s.to_ascii_lowercase_cow() {
58                    Cow::Borrowed(_) => {
59                        // it changes nothing
60                        // if there were any characters that needed to be lowercased, it had to be `Cow::Owned`
61                        Cow::Owned(s)
62                    },
63                    Cow::Owned(s) => Cow::Owned(s),
64                }
65            },
66        }
67    }
68}