mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
b07688dc2e
deprecate `std::char` constants and functions
similar to how constants in those modules for numeric types have been deprecated. The `std::char` module contains:
Three stable constants that this PR deprecates. These already link to their associated constant equivalents.
- `MAX`
- `REPLACEMENT_CHARACTER`
- `UNICODE_VERSION`
two unstable constants that this PR removes. The constants are already stablized as associated constants on `char`.
- `MAX_LEN_UTF8`
- `MAX_LEN_UTF16`
Four stable functions that this PR deprecates. These already link to their method equivalents.
- `fn decode_utf16`
- `fn from_digit`
- `fn from_u32`
- `fn from_u32_unchecked⚠`
discussion at [#t-libs > should `std::char::{MIN, MAX}` be deprecated?](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/should.20.60std.3A.3Achar.3A.3A.7BMIN.2C.20MAX.7D.60.20be.20deprecated.3F/with/579444750).
r? libs-api
662 lines
20 KiB
Rust
662 lines
20 KiB
Rust
//! Utilities for the `char` primitive type.
|
|
//!
|
|
//! *[See also the `char` primitive type](primitive@char).*
|
|
//!
|
|
//! The `char` type represents a single character. More specifically, since
|
|
//! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode
|
|
//! scalar value]', which is similar to, but not the same as, a '[Unicode code
|
|
//! point]'.
|
|
//!
|
|
//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
|
|
//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
|
|
//!
|
|
//! This module exists for technical reasons, the primary documentation for
|
|
//! `char` is directly on [the `char` primitive type][char] itself.
|
|
//!
|
|
//! This module is the home of the iterator implementations for the iterators
|
|
//! implemented on `char`, as well as some useful constants and conversion
|
|
//! functions that convert various types to `char`.
|
|
|
|
#![allow(non_snake_case)]
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
mod convert;
|
|
mod decode;
|
|
mod methods;
|
|
|
|
// stable re-exports
|
|
#[rustfmt::skip]
|
|
#[stable(feature = "try_from", since = "1.34.0")]
|
|
pub use self::convert::CharTryFromError;
|
|
#[stable(feature = "char_from_str", since = "1.20.0")]
|
|
pub use self::convert::ParseCharError;
|
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
|
pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
|
|
|
|
// perma-unstable re-exports
|
|
#[rustfmt::skip]
|
|
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
|
pub use self::methods::encode_utf16_raw; // perma-unstable
|
|
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
|
pub use self::methods::{encode_utf8_raw, encode_utf8_raw_unchecked}; // perma-unstable
|
|
|
|
#[rustfmt::skip]
|
|
use crate::ascii;
|
|
pub(crate) use self::methods::EscapeDebugExtArgs;
|
|
use crate::error::Error;
|
|
use crate::escape::{AlwaysEscaped, EscapeIterInner, MaybeEscaped};
|
|
use crate::fmt::{self, Write};
|
|
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
|
use crate::num::NonZero;
|
|
|
|
// UTF-8 ranges and tags for encoding characters
|
|
const TAG_CONT: u8 = 0b1000_0000;
|
|
const TAG_TWO_B: u8 = 0b1100_0000;
|
|
const TAG_THREE_B: u8 = 0b1110_0000;
|
|
const TAG_FOUR_B: u8 = 0b1111_0000;
|
|
const MAX_ONE_B: u32 = 0x80;
|
|
const MAX_TWO_B: u32 = 0x800;
|
|
const MAX_THREE_B: u32 = 0x10000;
|
|
|
|
/*
|
|
Lu Uppercase_Letter an uppercase letter
|
|
Ll Lowercase_Letter a lowercase letter
|
|
Lt Titlecase_Letter a digraphic character, with first part uppercase
|
|
Lm Modifier_Letter a modifier letter
|
|
Lo Other_Letter other letters, including syllables and ideographs
|
|
Mn Nonspacing_Mark a nonspacing combining mark (zero advance width)
|
|
Mc Spacing_Mark a spacing combining mark (positive advance width)
|
|
Me Enclosing_Mark an enclosing combining mark
|
|
Nd Decimal_Number a decimal digit
|
|
Nl Letter_Number a letterlike numeric character
|
|
No Other_Number a numeric character of other type
|
|
Pc Connector_Punctuation a connecting punctuation mark, like a tie
|
|
Pd Dash_Punctuation a dash or hyphen punctuation mark
|
|
Ps Open_Punctuation an opening punctuation mark (of a pair)
|
|
Pe Close_Punctuation a closing punctuation mark (of a pair)
|
|
Pi Initial_Punctuation an initial quotation mark
|
|
Pf Final_Punctuation a final quotation mark
|
|
Po Other_Punctuation a punctuation mark of other type
|
|
Sm Math_Symbol a symbol of primarily mathematical use
|
|
Sc Currency_Symbol a currency sign
|
|
Sk Modifier_Symbol a non-letterlike modifier symbol
|
|
So Other_Symbol a symbol of other type
|
|
Zs Space_Separator a space character (of various non-zero widths)
|
|
Zl Line_Separator U+2028 LINE SEPARATOR only
|
|
Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only
|
|
Cc Control a C0 or C1 control code
|
|
Cf Format a format control character
|
|
Cs Surrogate a surrogate code point
|
|
Co Private_Use a private-use character
|
|
Cn Unassigned a reserved unassigned code point or a noncharacter
|
|
*/
|
|
|
|
/// The highest valid code point a `char` can have, `'\u{10FFFF}'`. Use [`char::MAX`] instead.
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on `char`")]
|
|
pub const MAX: char = char::MAX;
|
|
|
|
/// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a
|
|
/// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead.
|
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
|
#[deprecated(
|
|
since = "TBD",
|
|
note = "replaced by the `REPLACEMENT_CHARACTER` associated constant on `char`"
|
|
)]
|
|
pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
|
|
|
|
/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
|
|
/// `char` and `str` methods are based on. Use [`char::UNICODE_VERSION`] instead.
|
|
#[stable(feature = "unicode_version", since = "1.45.0")]
|
|
#[deprecated(
|
|
since = "TBD",
|
|
note = "replaced by the `UNICODE_VERSION` associated constant on `char`"
|
|
)]
|
|
pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
|
|
|
|
/// Creates an iterator over the UTF-16 encoded code points in `iter`, returning
|
|
/// unpaired surrogates as `Err`s. Use [`char::decode_utf16`] instead.
|
|
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
|
#[deprecated(since = "TBD", note = "replaced by the `decode_utf16` method on `char`")]
|
|
#[inline]
|
|
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
|
|
self::decode::decode_utf16(iter)
|
|
}
|
|
|
|
/// Converts a `u32` to a `char`. Use [`char::from_u32`] instead.
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
|
|
#[deprecated(since = "TBD", note = "replaced by the `from_u32` method on `char`")]
|
|
#[must_use]
|
|
#[inline]
|
|
pub const fn from_u32(i: u32) -> Option<char> {
|
|
self::convert::from_u32(i)
|
|
}
|
|
|
|
/// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`]
|
|
/// instead.
|
|
#[stable(feature = "char_from_unchecked", since = "1.5.0")]
|
|
#[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
|
|
#[deprecated(since = "TBD", note = "replaced by the `from_u32_unchecked` method on `char`")]
|
|
#[must_use]
|
|
#[inline]
|
|
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
|
|
// SAFETY: the safety contract must be upheld by the caller.
|
|
unsafe { self::convert::from_u32_unchecked(i) }
|
|
}
|
|
|
|
/// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead.
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
|
|
#[deprecated(since = "TBD", note = "replaced by the `from_digit` method on `char`")]
|
|
#[must_use]
|
|
#[inline]
|
|
pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
|
self::convert::from_digit(num, radix)
|
|
}
|
|
|
|
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
|
/// character, as `char`s.
|
|
///
|
|
/// This `struct` is created by the [`escape_unicode`] method on [`char`]. See
|
|
/// its documentation for more.
|
|
///
|
|
/// [`escape_unicode`]: char::escape_unicode
|
|
#[derive(Clone, Debug)]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
pub struct EscapeUnicode(EscapeIterInner<10, AlwaysEscaped>);
|
|
|
|
impl EscapeUnicode {
|
|
#[inline]
|
|
const fn new(c: char) -> Self {
|
|
Self(EscapeIterInner::unicode(c))
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl Iterator for EscapeUnicode {
|
|
type Item = char;
|
|
|
|
#[inline]
|
|
fn next(&mut self) -> Option<char> {
|
|
self.0.next().map(char::from)
|
|
}
|
|
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let n = self.0.len();
|
|
(n, Some(n))
|
|
}
|
|
|
|
#[inline]
|
|
fn count(self) -> usize {
|
|
self.0.len()
|
|
}
|
|
|
|
#[inline]
|
|
fn last(mut self) -> Option<char> {
|
|
self.0.next_back().map(char::from)
|
|
}
|
|
|
|
#[inline]
|
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_by(n)
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "exact_size_escape", since = "1.11.0")]
|
|
impl ExactSizeIterator for EscapeUnicode {
|
|
#[inline]
|
|
fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
|
impl FusedIterator for EscapeUnicode {}
|
|
|
|
#[stable(feature = "char_struct_display", since = "1.16.0")]
|
|
impl fmt::Display for EscapeUnicode {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
/// An iterator that yields the literal escape code of a `char`.
|
|
///
|
|
/// This `struct` is created by the [`escape_default`] method on [`char`]. See
|
|
/// its documentation for more.
|
|
///
|
|
/// [`escape_default`]: char::escape_default
|
|
#[derive(Clone, Debug)]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
pub struct EscapeDefault(EscapeIterInner<10, AlwaysEscaped>);
|
|
|
|
impl EscapeDefault {
|
|
#[inline]
|
|
const fn printable(c: ascii::Char) -> Self {
|
|
Self(EscapeIterInner::ascii(c.to_u8()))
|
|
}
|
|
|
|
#[inline]
|
|
const fn backslash(c: ascii::Char) -> Self {
|
|
Self(EscapeIterInner::backslash(c))
|
|
}
|
|
|
|
#[inline]
|
|
const fn unicode(c: char) -> Self {
|
|
Self(EscapeIterInner::unicode(c))
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl Iterator for EscapeDefault {
|
|
type Item = char;
|
|
|
|
#[inline]
|
|
fn next(&mut self) -> Option<char> {
|
|
self.0.next().map(char::from)
|
|
}
|
|
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let n = self.0.len();
|
|
(n, Some(n))
|
|
}
|
|
|
|
#[inline]
|
|
fn count(self) -> usize {
|
|
self.0.len()
|
|
}
|
|
|
|
#[inline]
|
|
fn last(mut self) -> Option<char> {
|
|
self.0.next_back().map(char::from)
|
|
}
|
|
|
|
#[inline]
|
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_by(n)
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "exact_size_escape", since = "1.11.0")]
|
|
impl ExactSizeIterator for EscapeDefault {
|
|
#[inline]
|
|
fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
|
impl FusedIterator for EscapeDefault {}
|
|
|
|
#[stable(feature = "char_struct_display", since = "1.16.0")]
|
|
impl fmt::Display for EscapeDefault {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
/// An iterator that yields the literal escape code of a `char`.
|
|
///
|
|
/// This `struct` is created by the [`escape_debug`] method on [`char`]. See its
|
|
/// documentation for more.
|
|
///
|
|
/// [`escape_debug`]: char::escape_debug
|
|
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
|
#[derive(Clone, Debug)]
|
|
pub struct EscapeDebug(EscapeIterInner<10, MaybeEscaped>);
|
|
|
|
impl EscapeDebug {
|
|
#[inline]
|
|
const fn printable(chr: char) -> Self {
|
|
Self(EscapeIterInner::printable(chr))
|
|
}
|
|
|
|
#[inline]
|
|
const fn backslash(c: ascii::Char) -> Self {
|
|
Self(EscapeIterInner::backslash(c))
|
|
}
|
|
|
|
#[inline]
|
|
const fn unicode(c: char) -> Self {
|
|
Self(EscapeIterInner::unicode(c))
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
|
impl Iterator for EscapeDebug {
|
|
type Item = char;
|
|
|
|
#[inline]
|
|
fn next(&mut self) -> Option<char> {
|
|
self.0.next()
|
|
}
|
|
|
|
#[inline]
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let n = self.len();
|
|
(n, Some(n))
|
|
}
|
|
|
|
#[inline]
|
|
fn count(self) -> usize {
|
|
self.len()
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
|
impl ExactSizeIterator for EscapeDebug {
|
|
fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
|
impl FusedIterator for EscapeDebug {}
|
|
|
|
#[stable(feature = "char_escape_debug", since = "1.20.0")]
|
|
impl fmt::Display for EscapeDebug {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
macro_rules! casemappingiter_impls {
|
|
(
|
|
#[$stab:meta]
|
|
#[$dendstab:meta]
|
|
#[$fusedstab:meta]
|
|
#[$exactstab:meta]
|
|
#[$displaystab:meta]
|
|
$(#[$attr:meta])*
|
|
$ITER_NAME:ident
|
|
) => {
|
|
$(#[$attr])*
|
|
#[$stab]
|
|
#[derive(Debug, Clone)]
|
|
pub struct $ITER_NAME(CaseMappingIter);
|
|
|
|
#[$stab]
|
|
impl Iterator for $ITER_NAME {
|
|
type Item = char;
|
|
fn next(&mut self) -> Option<char> {
|
|
self.0.next()
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
self.0.size_hint()
|
|
}
|
|
|
|
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
|
|
where
|
|
Fold: FnMut(Acc, Self::Item) -> Acc,
|
|
{
|
|
self.0.fold(init, fold)
|
|
}
|
|
|
|
fn count(self) -> usize {
|
|
self.0.count()
|
|
}
|
|
|
|
fn last(self) -> Option<Self::Item> {
|
|
self.0.last()
|
|
}
|
|
|
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_by(n)
|
|
}
|
|
|
|
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
|
|
// SAFETY: just forwarding requirements to caller
|
|
unsafe { self.0.__iterator_get_unchecked(idx) }
|
|
}
|
|
}
|
|
|
|
#[$dendstab]
|
|
impl DoubleEndedIterator for $ITER_NAME {
|
|
fn next_back(&mut self) -> Option<char> {
|
|
self.0.next_back()
|
|
}
|
|
|
|
fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
|
|
where
|
|
Fold: FnMut(Acc, Self::Item) -> Acc,
|
|
{
|
|
self.0.rfold(init, rfold)
|
|
}
|
|
|
|
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_back_by(n)
|
|
}
|
|
}
|
|
|
|
#[$fusedstab]
|
|
impl FusedIterator for $ITER_NAME {}
|
|
|
|
#[$exactstab]
|
|
impl ExactSizeIterator for $ITER_NAME {
|
|
fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
|
|
fn is_empty(&self) -> bool {
|
|
self.0.is_empty()
|
|
}
|
|
}
|
|
|
|
// SAFETY: forwards to inner `array::IntoIter`
|
|
#[unstable(feature = "trusted_len", issue = "37572")]
|
|
unsafe impl TrustedLen for $ITER_NAME {}
|
|
|
|
// SAFETY: forwards to inner `array::IntoIter`
|
|
#[doc(hidden)]
|
|
#[unstable(feature = "std_internals", issue = "none")]
|
|
unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME {
|
|
const MAY_HAVE_SIDE_EFFECT: bool = false;
|
|
}
|
|
|
|
// SAFETY: this iter has no subtypes/supertypes
|
|
#[doc(hidden)]
|
|
#[unstable(feature = "std_internals", issue = "none")]
|
|
unsafe impl TrustedRandomAccess for $ITER_NAME {}
|
|
|
|
#[$displaystab]
|
|
impl fmt::Display for $ITER_NAME {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
casemappingiter_impls! {
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
|
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
|
|
#[stable(feature = "char_struct_display", since = "1.16.0")]
|
|
/// Returns an iterator that yields the uppercase equivalent of a `char`.
|
|
///
|
|
/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
|
|
/// its documentation for more.
|
|
///
|
|
/// [`to_uppercase`]: char::to_uppercase
|
|
ToUppercase
|
|
}
|
|
|
|
casemappingiter_impls! {
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
/// Returns an iterator that yields the titlecase equivalent of a `char`.
|
|
///
|
|
/// This `struct` is created by the [`to_titlecase`] method on [`char`]. See
|
|
/// its documentation for more.
|
|
///
|
|
/// [`to_titlecase`]: char::to_titlecase
|
|
ToTitlecase
|
|
}
|
|
|
|
casemappingiter_impls! {
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
|
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
|
|
#[stable(feature = "char_struct_display", since = "1.16.0")]
|
|
/// Returns an iterator that yields the lowercase equivalent of a `char`.
|
|
///
|
|
/// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
|
|
/// its documentation for more.
|
|
///
|
|
/// [`to_lowercase`]: char::to_lowercase
|
|
ToLowercase
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct CaseMappingIter(core::array::IntoIter<char, 3>);
|
|
|
|
impl CaseMappingIter {
|
|
#[inline]
|
|
fn new(chars: [char; 3]) -> CaseMappingIter {
|
|
let mut iter = chars.into_iter();
|
|
if chars[2] == '\0' {
|
|
iter.next_back();
|
|
if chars[1] == '\0' {
|
|
iter.next_back();
|
|
|
|
// Deliberately don't check `chars[0]`,
|
|
// as '\0' lowercases to itself
|
|
}
|
|
}
|
|
CaseMappingIter(iter)
|
|
}
|
|
}
|
|
|
|
impl Iterator for CaseMappingIter {
|
|
type Item = char;
|
|
|
|
fn next(&mut self) -> Option<char> {
|
|
self.0.next()
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
self.0.size_hint()
|
|
}
|
|
|
|
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
|
|
where
|
|
Fold: FnMut(Acc, Self::Item) -> Acc,
|
|
{
|
|
self.0.fold(init, fold)
|
|
}
|
|
|
|
fn count(self) -> usize {
|
|
self.0.count()
|
|
}
|
|
|
|
fn last(self) -> Option<Self::Item> {
|
|
self.0.last()
|
|
}
|
|
|
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_by(n)
|
|
}
|
|
|
|
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
|
|
// SAFETY: just forwarding requirements to caller
|
|
unsafe { self.0.__iterator_get_unchecked(idx) }
|
|
}
|
|
}
|
|
|
|
impl DoubleEndedIterator for CaseMappingIter {
|
|
fn next_back(&mut self) -> Option<char> {
|
|
self.0.next_back()
|
|
}
|
|
|
|
fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
|
|
where
|
|
Fold: FnMut(Acc, Self::Item) -> Acc,
|
|
{
|
|
self.0.rfold(init, rfold)
|
|
}
|
|
|
|
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
|
self.0.advance_back_by(n)
|
|
}
|
|
}
|
|
|
|
impl ExactSizeIterator for CaseMappingIter {
|
|
fn len(&self) -> usize {
|
|
self.0.len()
|
|
}
|
|
|
|
fn is_empty(&self) -> bool {
|
|
self.0.is_empty()
|
|
}
|
|
}
|
|
|
|
impl FusedIterator for CaseMappingIter {}
|
|
|
|
// SAFETY: forwards to inner `array::IntoIter`
|
|
unsafe impl TrustedLen for CaseMappingIter {}
|
|
|
|
// SAFETY: forwards to inner `array::IntoIter`
|
|
unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter {
|
|
const MAY_HAVE_SIDE_EFFECT: bool = false;
|
|
}
|
|
|
|
// SAFETY: `CaseMappingIter` has no subtypes/supertypes
|
|
unsafe impl TrustedRandomAccess for CaseMappingIter {}
|
|
|
|
impl fmt::Display for CaseMappingIter {
|
|
#[inline]
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
for c in self.0.clone() {
|
|
f.write_char(c)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// The error type returned when a checked char conversion fails.
|
|
#[stable(feature = "u8_from_char", since = "1.59.0")]
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
|
pub struct TryFromCharError(pub(crate) ());
|
|
|
|
#[stable(feature = "u8_from_char", since = "1.59.0")]
|
|
impl fmt::Display for TryFromCharError {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
"unicode code point out of range".fmt(fmt)
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "u8_from_char", since = "1.59.0")]
|
|
impl Error for TryFromCharError {}
|
|
|
|
/// The case of a cased character,
|
|
/// as returned by [`char::case`].
|
|
///
|
|
/// Titlecase characters conceptually are composed of an uppercase portion
|
|
/// followed by a lowercase portion.
|
|
/// The variant discriminants represent this:
|
|
/// the most significant bit represents whether the case
|
|
/// conceptually starts as uppercase, while the least significant bit
|
|
/// represents whether it conceptually ends as uppercase.
|
|
#[unstable(feature = "titlecase", issue = "153892")]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
pub enum CharCase {
|
|
/// Lowercase. Corresponds to the `Lowercase` Unicode property.
|
|
Lower = 0b00,
|
|
/// Titlecase. Corresponds to the `Titlecase_Letter` Unicode general category.
|
|
Title = 0b10,
|
|
/// Uppercase. Corresponds to the `Uppercase` Unicode property.
|
|
Upper = 0b11,
|
|
}
|