Skip to content

Commit a2512b4

Browse files
Add PartialEq impls to the character case iterators
Allows easily checking whether a string is in a particular case
1 parent a6b883a commit a2512b4

2 files changed

Lines changed: 87 additions & 3 deletions

File tree

library/core/src/char/methods.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,8 @@ impl char {
11381138
}
11391139

11401140
/// Returns an iterator that yields the lowercase mapping of this `char` as one or more
1141-
/// `char`s.
1141+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1142+
/// and [`PartialEq`].
11421143
///
11431144
/// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
11441145
///
@@ -1196,6 +1197,13 @@ impl char {
11961197
/// // convert into themselves.
11971198
/// assert_eq!('山'.to_lowercase().to_string(), "山");
11981199
/// ```
1200+
///
1201+
/// Check if a string is in lowercase:
1202+
///
1203+
/// ```
1204+
/// let s = "abcde\u{0301} 山";
1205+
/// assert!(s.chars().all(|c| c.to_lowercase() == c));
1206+
/// ```
11991207
#[must_use = "this returns the lowercased character as a new iterator, \
12001208
without modifying the original"]
12011209
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1205,7 +1213,8 @@ impl char {
12051213
}
12061214

12071215
/// Returns an iterator that yields the titlecase mapping of this `char` as one or more
1208-
/// `char`s.
1216+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1217+
/// and [`PartialEq`].
12091218
///
12101219
/// If this `char` does not have an titlecase mapping, the iterator yields the same `char`.
12111220
///
@@ -1268,6 +1277,21 @@ impl char {
12681277
/// assert_eq!('山'.to_titlecase().to_string(), "山");
12691278
/// ```
12701279
///
1280+
/// Check if a word is in titlecase:
1281+
///
1282+
/// ```
1283+
/// #![feature(titlecase)]
1284+
/// let word = "Dross";
1285+
/// let mut chars = word.chars();
1286+
/// let first_cased_char = chars.find(|c| c.is_cased());
1287+
/// let word_is_in_titlecase = if let Some(f) = first_cased_char {
1288+
/// f.to_titlecase() == f && chars.all(|c| c.to_lowercase() == c)
1289+
/// } else {
1290+
/// true
1291+
/// };
1292+
/// assert!(word_is_in_titlecase);
1293+
/// ```
1294+
///
12711295
/// # Note on locale
12721296
///
12731297
/// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
@@ -1303,7 +1327,8 @@ impl char {
13031327
}
13041328

13051329
/// Returns an iterator that yields the uppercase mapping of this `char` as one or more
1306-
/// `char`s.
1330+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1331+
/// and [`PartialEq`].
13071332
///
13081333
/// If this `char` does not have an uppercase mapping, the iterator yields the same `char`.
13091334
///
@@ -1362,6 +1387,13 @@ impl char {
13621387
/// assert_eq!('山'.to_uppercase().to_string(), "山");
13631388
/// ```
13641389
///
1390+
/// Check if a string is in uppercase:
1391+
///
1392+
/// ```
1393+
/// let s = "ABCDE\u{0301} 山";
1394+
/// assert!(s.chars().all(|c| c.to_uppercase() == c));
1395+
/// ```
1396+
///
13651397
/// # Note on locale
13661398
///
13671399
/// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:

library/core/src/char/mod.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ macro_rules! casemappingiter_impls {
369369
#[$fusedstab:meta]
370370
#[$exactstab:meta]
371371
#[$displaystab:meta]
372+
#[$partialstab:meta]
372373
$(#[$attr:meta])*
373374
$ITER_NAME:ident
374375
) => {
@@ -468,6 +469,38 @@ macro_rules! casemappingiter_impls {
468469
fmt::Display::fmt(&self.0, f)
469470
}
470471
}
472+
473+
#[$partialstab]
474+
impl PartialEq<ToUppercase> for $ITER_NAME {
475+
#[inline]
476+
fn eq(&self, other: &ToUppercase) -> bool {
477+
self.0 == other.0
478+
}
479+
}
480+
481+
#[unstable(feature = "titlecase", issue = "none")]
482+
impl PartialEq<ToTitlecase> for $ITER_NAME {
483+
#[inline]
484+
fn eq(&self, other: &ToTitlecase) -> bool {
485+
self.0 == other.0
486+
}
487+
}
488+
489+
#[$partialstab]
490+
impl PartialEq<ToLowercase> for $ITER_NAME {
491+
#[inline]
492+
fn eq(&self, other: &ToLowercase) -> bool {
493+
self.0 == other.0
494+
}
495+
}
496+
497+
#[$partialstab]
498+
impl PartialEq<char> for $ITER_NAME {
499+
#[inline]
500+
fn eq(&self, other: &char) -> bool {
501+
self.0 == *other
502+
}
503+
}
471504
}
472505
}
473506

@@ -477,6 +510,7 @@ casemappingiter_impls! {
477510
#[stable(feature = "fused", since = "1.26.0")]
478511
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
479512
#[stable(feature = "char_struct_display", since = "1.16.0")]
513+
#[stable(feature = "iter_partialeq", since = "CURRENT_RUSTC_VERSION")]
480514
/// Returns an iterator that yields the uppercase equivalent of a `char`.
481515
///
482516
/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
@@ -492,6 +526,7 @@ casemappingiter_impls! {
492526
#[unstable(feature = "titlecase", issue = "none")]
493527
#[unstable(feature = "titlecase", issue = "none")]
494528
#[unstable(feature = "titlecase", issue = "none")]
529+
#[unstable(feature = "titlecase", issue = "none")]
495530
/// Returns an iterator that yields the titlecase equivalent of a `char`.
496531
///
497532
/// This `struct` is created by the [`to_titlecase`] method on [`char`]. See
@@ -507,6 +542,7 @@ casemappingiter_impls! {
507542
#[stable(feature = "fused", since = "1.26.0")]
508543
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
509544
#[stable(feature = "char_struct_display", since = "1.16.0")]
545+
#[stable(feature = "iter_partialeq", since = "CURRENT_RUSTC_VERSION")]
510546
/// Returns an iterator that yields the lowercase equivalent of a `char`.
511547
///
512548
/// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
@@ -622,6 +658,22 @@ impl fmt::Display for CaseMappingIter {
622658
}
623659
}
624660

661+
impl PartialEq for CaseMappingIter {
662+
#[inline]
663+
fn eq(&self, other: &Self) -> bool {
664+
self.0.as_slice() == other.0.as_slice()
665+
}
666+
}
667+
668+
impl Eq for CaseMappingIter {}
669+
670+
impl PartialEq<char> for CaseMappingIter {
671+
#[inline]
672+
fn eq(&self, other: &char) -> bool {
673+
self.0.as_slice() == &[*other]
674+
}
675+
}
676+
625677
/// The error type returned when a checked char conversion fails.
626678
#[stable(feature = "u8_from_char", since = "1.59.0")]
627679
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)