Skip to content

Commit 373e272

Browse files
Add char::case
1 parent 3015053 commit 373e272

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

library/core/src/char/methods.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,39 @@ impl char {
779779
}
780780
}
781781

782+
/// Returns the case of this character:
783+
/// [`Some(CharCase::Upper)`][`CharCase::Upper`] if [`self.is_uppercase()`][`char::is_uppercase`],
784+
/// [`Some(CharCase::Lower)`][`CharCase::Lower`] if [`self.is_lowercase()`][`char::is_lowercase`],
785+
/// [`Some(CharCase::Title)`][`CharCase::Title`] if [`self.is_titlecase()`][`char::is_titlecase`], and
786+
/// `None` if [`!self.is_cased()`][`char::is_cased`].
787+
///
788+
/// # Examples
789+
///
790+
/// ```
791+
/// #![feature(titlecase)]
792+
/// use core::char::CharCase;
793+
/// assert_eq!('a'.case(), Some(CharCase::Lower));
794+
/// assert_eq!('δ'.case(), Some(CharCase::Lower));
795+
/// assert_eq!('A'.case(), Some(CharCase::Upper));
796+
/// assert_eq!('Δ'.case(), Some(CharCase::Upper));
797+
/// assert_eq!('Dž'.case(), Some(CharCase::Title));
798+
/// assert_eq!('中'.case(), None);
799+
/// ```
800+
#[must_use]
801+
#[unstable(feature = "titlecase", issue = "none")]
802+
#[inline]
803+
pub fn case(self) -> Option<CharCase> {
804+
match self {
805+
'A'..='Z' => Some(CharCase::Upper),
806+
'a'..='z' => Some(CharCase::Lower),
807+
'\0'..='\u{A9}' => None,
808+
_ if !self.is_cased() => None,
809+
_ if self.is_lowercase() => Some(CharCase::Lower),
810+
_ if self.is_uppercase() => Some(CharCase::Upper),
811+
_ => Some(CharCase::Title),
812+
}
813+
}
814+
782815
/// Returns `true` if this `char` has the `Lowercase` property.
783816
///
784817
/// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and

library/core/src/char/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,3 +613,16 @@ impl fmt::Display for TryFromCharError {
613613

614614
#[stable(feature = "u8_from_char", since = "1.59.0")]
615615
impl Error for TryFromCharError {}
616+
617+
/// The case of a cased character,
618+
/// as returned by [`char::case`].
619+
#[unstable(feature = "titlecase", issue = "none")]
620+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
621+
pub enum CharCase {
622+
/// Lowercase. Corresponds to the `Lowercase` Unicode property.
623+
Lower = 0b00,
624+
/// Titlecase. Corresponds to the `Titlecase_Letter` Unicode general category.
625+
Title = 0b10,
626+
/// Uppercase. Corresponds to the `Uppercase` Unicode property.
627+
Upper = 0b11,
628+
}

library/core/tests/char.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::str::FromStr;
2-
use std::{char, str};
2+
use std::{
3+
char::{self, CharCase},
4+
str,
5+
};
36

47
#[test]
58
fn test_convert() {
@@ -52,6 +55,18 @@ fn test_is_cased() {
5255
assert!(!'攂'.is_cased());
5356
}
5457

58+
#[test]
59+
fn test_char_case() {
60+
for c in '\0'..='\u{10FFFF}' {
61+
match c.case() {
62+
None => assert!(!c.is_cased()),
63+
Some(CharCase::Lower) => assert!(c.is_lowercase()),
64+
Some(CharCase::Upper) => assert!(c.is_uppercase()),
65+
Some(CharCase::Title) => assert!(c.is_titlecase()),
66+
}
67+
}
68+
}
69+
5570
#[test]
5671
fn test_is_lowercase() {
5772
assert!('a'.is_lowercase());

0 commit comments

Comments
 (0)