Skip to content

Commit fe5d72b

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

File tree

2 files changed

+87
-3
lines changed

2 files changed

+87
-3
lines changed

library/core/src/char/methods.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,8 @@ impl char {
10761076
}
10771077

10781078
/// Returns an iterator that yields the lowercase mapping of this `char` as one or more
1079-
/// `char`s.
1079+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1080+
/// and [`PartialEq`].
10801081
///
10811082
/// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
10821083
///
@@ -1134,6 +1135,13 @@ impl char {
11341135
/// // convert into themselves.
11351136
/// assert_eq!('山'.to_lowercase().to_string(), "山");
11361137
/// ```
1138+
///
1139+
/// Check if a string is in lowercase:
1140+
///
1141+
/// ```
1142+
/// let s = "abcde\u{0301} 山";
1143+
/// assert!(s.chars().all(|c| c.to_lowercase() == c));
1144+
/// ```
11371145
#[must_use = "this returns the lowercased character as a new iterator, \
11381146
without modifying the original"]
11391147
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1143,7 +1151,8 @@ impl char {
11431151
}
11441152

11451153
/// Returns an iterator that yields the titlecase mapping of this `char` as one or more
1146-
/// `char`s.
1154+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1155+
/// and [`PartialEq`].
11471156
///
11481157
/// If this `char` does not have an titlecase mapping, the iterator yields the same `char`.
11491158
///
@@ -1206,6 +1215,21 @@ impl char {
12061215
/// assert_eq!('山'.to_titlecase().to_string(), "山");
12071216
/// ```
12081217
///
1218+
/// Check if a word is in titlecase:
1219+
///
1220+
/// ```
1221+
/// #![feature(titlecase)]
1222+
/// let word = "Dross";
1223+
/// let mut chars = word.chars();
1224+
/// let first_cased_char = chars.find(|c| c.is_cased());
1225+
/// let word_is_in_titlecase = if let Some(f) = first_cased_char {
1226+
/// f.to_titlecase() == f && chars.all(|c| c.to_lowercase() == c)
1227+
/// } else {
1228+
/// true
1229+
/// };
1230+
/// assert!(word_is_in_titlecase);
1231+
/// ```
1232+
///
12091233
/// # Note on locale
12101234
///
12111235
/// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
@@ -1241,7 +1265,8 @@ impl char {
12411265
}
12421266

12431267
/// Returns an iterator that yields the uppercase mapping of this `char` as one or more
1244-
/// `char`s.
1268+
/// `char`s. The iterator also has implementations of [`Display`][core::fmt::Display]
1269+
/// and [`PartialEq`].
12451270
///
12461271
/// If this `char` does not have an uppercase mapping, the iterator yields the same `char`.
12471272
///
@@ -1300,6 +1325,13 @@ impl char {
13001325
/// assert_eq!('山'.to_uppercase().to_string(), "山");
13011326
/// ```
13021327
///
1328+
/// Check if a string is in uppercase:
1329+
///
1330+
/// ```
1331+
/// let s = "ABCDE\u{0301} 山";
1332+
/// assert!(s.chars().all(|c| c.to_uppercase() == c));
1333+
/// ```
1334+
///
13031335
/// # Note on locale
13041336
///
13051337
/// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:

library/core/src/char/mod.rs

+52
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ macro_rules! casemappingiter_impls {
380380
#[$fusedstab:meta]
381381
#[$exactstab:meta]
382382
#[$displaystab:meta]
383+
#[$partialstab:meta]
383384
$(#[$attr:meta])*
384385
$ITER_NAME:ident
385386
) => {
@@ -478,6 +479,38 @@ macro_rules! casemappingiter_impls {
478479
fmt::Display::fmt(&self.0, f)
479480
}
480481
}
482+
483+
#[$partialstab]
484+
impl PartialEq<ToUppercase> for $ITER_NAME {
485+
#[inline]
486+
fn eq(&self, other: &ToUppercase) -> bool {
487+
self.0 == other.0
488+
}
489+
}
490+
491+
#[unstable(feature = "titlecase", issue = "none")]
492+
impl PartialEq<ToTitlecase> for $ITER_NAME {
493+
#[inline]
494+
fn eq(&self, other: &ToTitlecase) -> bool {
495+
self.0 == other.0
496+
}
497+
}
498+
499+
#[$partialstab]
500+
impl PartialEq<ToLowercase> for $ITER_NAME {
501+
#[inline]
502+
fn eq(&self, other: &ToLowercase) -> bool {
503+
self.0 == other.0
504+
}
505+
}
506+
507+
#[$partialstab]
508+
impl PartialEq<char> for $ITER_NAME {
509+
#[inline]
510+
fn eq(&self, other: &char) -> bool {
511+
self.0 == *other
512+
}
513+
}
481514
}
482515
}
483516

@@ -487,6 +520,7 @@ casemappingiter_impls! {
487520
#[stable(feature = "fused", since = "1.26.0")]
488521
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
489522
#[stable(feature = "char_struct_display", since = "1.16.0")]
523+
#[stable(feature = "iter_partialeq", since = "CURRENT_RUSTC_VERSION")]
490524
/// Returns an iterator that yields the uppercase equivalent of a `char`.
491525
///
492526
/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
@@ -502,6 +536,7 @@ casemappingiter_impls! {
502536
#[unstable(feature = "titlecase", issue = "none")]
503537
#[unstable(feature = "titlecase", issue = "none")]
504538
#[unstable(feature = "titlecase", issue = "none")]
539+
#[unstable(feature = "titlecase", issue = "none")]
505540
/// Returns an iterator that yields the titlecase equivalent of a `char`.
506541
///
507542
/// This `struct` is created by the [`to_titlecase`] method on [`char`]. See
@@ -517,6 +552,7 @@ casemappingiter_impls! {
517552
#[stable(feature = "fused", since = "1.26.0")]
518553
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
519554
#[stable(feature = "char_struct_display", since = "1.16.0")]
555+
#[stable(feature = "iter_partialeq", since = "CURRENT_RUSTC_VERSION")]
520556
/// Returns an iterator that yields the lowercase equivalent of a `char`.
521557
///
522558
/// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
@@ -632,6 +668,22 @@ impl fmt::Display for CaseMappingIter {
632668
}
633669
}
634670

671+
impl PartialEq for CaseMappingIter {
672+
#[inline]
673+
fn eq(&self, other: &Self) -> bool {
674+
self.0.as_slice() == other.0.as_slice()
675+
}
676+
}
677+
678+
impl Eq for CaseMappingIter {}
679+
680+
impl PartialEq<char> for CaseMappingIter {
681+
#[inline]
682+
fn eq(&self, other: &char) -> bool {
683+
self.0.as_slice() == &[*other]
684+
}
685+
}
686+
635687
/// The error type returned when a checked char conversion fails.
636688
#[stable(feature = "u8_from_char", since = "1.59.0")]
637689
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)