Skip to main content

core/char/
methods.rs

1//! impl char {}
2
3#![expect(clippy::manual_is_ascii_check, reason = "this module implements various is_ascii checks")]
4
5use super::*;
6use crate::panic::const_panic;
7use crate::slice;
8use crate::str::from_utf8_unchecked_mut;
9use crate::ub_checks::assert_unsafe_precondition;
10use crate::unicode::{self, conversions};
11
12impl char {
13    /// The lowest valid code point a `char` can have, `'\0'`.
14    ///
15    /// Unlike integer types, `char` actually has a gap in the middle,
16    /// meaning that the range of possible `char`s is smaller than you
17    /// might expect. Ranges of `char` will automatically hop this gap
18    /// for you:
19    ///
20    /// ```
21    /// let dist = u32::from(char::MAX) - u32::from(char::MIN);
22    /// let size = (char::MIN..=char::MAX).count() as u32;
23    /// assert!(size < dist);
24    /// ```
25    ///
26    /// Despite this gap, the `MIN` and [`MAX`] values can be used as bounds for
27    /// all `char` values.
28    ///
29    /// [`MAX`]: char::MAX
30    ///
31    /// # Examples
32    ///
33    /// ```
34    /// # fn something_which_returns_char() -> char { 'a' }
35    /// let c: char = something_which_returns_char();
36    /// assert!(char::MIN <= c);
37    ///
38    /// let value_at_min = u32::from(char::MIN);
39    /// assert_eq!(char::from_u32(value_at_min), Some('\0'));
40    /// ```
41    #[stable(feature = "char_min", since = "1.83.0")]
42    pub const MIN: char = '\0';
43
44    /// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
45    ///
46    /// Unlike integer types, `char` actually has a gap in the middle,
47    /// meaning that the range of possible `char`s is smaller than you
48    /// might expect. Ranges of `char` will automatically hop this gap
49    /// for you:
50    ///
51    /// ```
52    /// let dist = u32::from(char::MAX) - u32::from(char::MIN);
53    /// let size = (char::MIN..=char::MAX).count() as u32;
54    /// assert!(size < dist);
55    /// ```
56    ///
57    /// Despite this gap, the [`MIN`] and `MAX` values can be used as bounds for
58    /// all `char` values.
59    ///
60    /// [`MIN`]: char::MIN
61    ///
62    /// # Examples
63    ///
64    /// ```
65    /// # fn something_which_returns_char() -> char { 'a' }
66    /// let c: char = something_which_returns_char();
67    /// assert!(c <= char::MAX);
68    ///
69    /// let value_at_max = u32::from(char::MAX);
70    /// assert_eq!(char::from_u32(value_at_max), Some('\u{10FFFF}'));
71    /// assert_eq!(char::from_u32(value_at_max + 1), None);
72    /// ```
73    #[stable(feature = "assoc_char_consts", since = "1.52.0")]
74    pub const MAX: char = '\u{10FFFF}';
75
76    /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to
77    /// UTF-8 encoding.
78    #[stable(feature = "char_max_len_assoc", since = "1.93.0")]
79    pub const MAX_LEN_UTF8: usize = 4;
80
81    /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char`
82    /// to UTF-16 encoding.
83    #[stable(feature = "char_max_len_assoc", since = "1.93.0")]
84    pub const MAX_LEN_UTF16: usize = 2;
85
86    /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a
87    /// decoding error.
88    ///
89    /// It can occur, for example, when giving ill-formed UTF-8 bytes to
90    /// [`String::from_utf8_lossy`](../std/string/struct.String.html#method.from_utf8_lossy).
91    #[stable(feature = "assoc_char_consts", since = "1.52.0")]
92    pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';
93
94    /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
95    /// `char` and `str` methods are based on.
96    ///
97    /// New versions of Unicode are released regularly, and subsequently all methods
98    /// in the standard library depending on Unicode are updated. Therefore, the
99    /// behavior of some `char` and `str` methods, and the value of this constant,
100    /// change over time (within the boundaries of Unicode's [stability policies]).
101    /// This is *not* considered to be a breaking change.
102    ///
103    /// [stability policies]: https://www.unicode.org/policies/stability_policy.html
104    ///
105    /// The version numbering scheme is explained in
106    /// [Section 3.1 (Version Numbering)] of the Unicode Standard.
107    ///
108    /// [Section 3.1 (Version Numbering)]: https://www.unicode.org/versions/latest/core-spec/chapter-3/#G49512
109    #[stable(feature = "assoc_char_consts", since = "1.52.0")]
110    pub const UNICODE_VERSION: (u8, u8, u8) = crate::unicode::UNICODE_VERSION;
111
112    /// Creates an iterator over the native endian UTF-16 encoded code points in `iter`,
113    /// returning unpaired surrogates as `Err`s.
114    ///
115    /// # Examples
116    ///
117    /// Basic usage:
118    ///
119    /// ```
120    /// // 𝄞mus<invalid>ic<invalid>
121    /// let v = [
122    ///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
123    /// ];
124    ///
125    /// assert_eq!(
126    ///     char::decode_utf16(v)
127    ///         .map(|r| r.map_err(|e| e.unpaired_surrogate()))
128    ///         .collect::<Vec<_>>(),
129    ///     vec![
130    ///         Ok('𝄞'),
131    ///         Ok('m'), Ok('u'), Ok('s'),
132    ///         Err(0xDD1E),
133    ///         Ok('i'), Ok('c'),
134    ///         Err(0xD834)
135    ///     ]
136    /// );
137    /// ```
138    ///
139    /// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
140    ///
141    /// ```
142    /// // 𝄞mus<invalid>ic<invalid>
143    /// let v = [
144    ///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
145    /// ];
146    ///
147    /// assert_eq!(
148    ///     char::decode_utf16(v)
149    ///        .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
150    ///        .collect::<String>(),
151    ///     "𝄞mus�ic�"
152    /// );
153    /// ```
154    #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
155    #[inline]
156    pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
157        super::decode::decode_utf16(iter)
158    }
159
160    /// Converts a `u32` to a `char`.
161    ///
162    /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
163    /// [`as`](../std/keyword.as.html):
164    ///
165    /// ```
166    /// let c = '💯';
167    /// let i = c as u32;
168    ///
169    /// assert_eq!(128175, i);
170    /// ```
171    ///
172    /// However, the reverse is not true: not all valid [`u32`]s are valid
173    /// `char`s. `from_u32()` will return `None` if the input is not a valid value
174    /// for a `char`.
175    ///
176    /// For an unsafe version of this function which ignores these checks, see
177    /// [`from_u32_unchecked`].
178    ///
179    /// [`from_u32_unchecked`]: #method.from_u32_unchecked
180    ///
181    /// # Examples
182    ///
183    /// Basic usage:
184    ///
185    /// ```
186    /// let c = char::from_u32(0x2764);
187    ///
188    /// assert_eq!(Some('❤'), c);
189    /// ```
190    ///
191    /// Returning `None` when the input is not a valid `char`:
192    ///
193    /// ```
194    /// let c = char::from_u32(0x110000);
195    ///
196    /// assert_eq!(None, c);
197    /// ```
198    #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
199    #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
200    #[must_use]
201    #[inline]
202    pub const fn from_u32(i: u32) -> Option<char> {
203        super::convert::from_u32(i)
204    }
205
206    /// Converts a `u32` to a `char`, ignoring validity.
207    ///
208    /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
209    /// `as`:
210    ///
211    /// ```
212    /// let c = '💯';
213    /// let i = c as u32;
214    ///
215    /// assert_eq!(128175, i);
216    /// ```
217    ///
218    /// However, the reverse is not true: not all valid [`u32`]s are valid
219    /// `char`s. `from_u32_unchecked()` will ignore this, and blindly cast to
220    /// `char`, possibly creating an invalid one.
221    ///
222    /// # Safety
223    ///
224    /// This function is unsafe, as it may construct invalid `char` values.
225    ///
226    /// For a safe version of this function, see the [`from_u32`] function.
227    ///
228    /// [`from_u32`]: #method.from_u32
229    ///
230    /// # Examples
231    ///
232    /// Basic usage:
233    ///
234    /// ```
235    /// let c = unsafe { char::from_u32_unchecked(0x2764) };
236    ///
237    /// assert_eq!('❤', c);
238    /// ```
239    #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
240    #[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
241    #[must_use]
242    #[inline]
243    pub const unsafe fn from_u32_unchecked(i: u32) -> char {
244        // SAFETY: the safety contract must be upheld by the caller.
245        unsafe { super::convert::from_u32_unchecked(i) }
246    }
247
248    /// Converts a digit in the given radix to a `char`.
249    ///
250    /// A 'radix' here is sometimes also called a 'base'. A radix of two
251    /// indicates a binary number, a radix of ten, decimal, and a radix of
252    /// sixteen, hexadecimal, to give some common values. Arbitrary
253    /// radices are supported.
254    ///
255    /// `from_digit()` will return `None` if the input is not a digit in
256    /// the given radix.
257    ///
258    /// # Panics
259    ///
260    /// Panics if given a radix larger than 36.
261    ///
262    /// # Examples
263    ///
264    /// Basic usage:
265    ///
266    /// ```
267    /// let c = char::from_digit(4, 10);
268    ///
269    /// assert_eq!(Some('4'), c);
270    ///
271    /// // Decimal 11 is a single digit in base 16
272    /// let c = char::from_digit(11, 16);
273    ///
274    /// assert_eq!(Some('b'), c);
275    /// ```
276    ///
277    /// Returning `None` when the input is not a digit:
278    ///
279    /// ```
280    /// let c = char::from_digit(20, 10);
281    ///
282    /// assert_eq!(None, c);
283    /// ```
284    ///
285    /// Passing a large radix, causing a panic:
286    ///
287    /// ```should_panic
288    /// // this panics
289    /// let _c = char::from_digit(1, 37);
290    /// ```
291    #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
292    #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
293    #[must_use]
294    #[inline]
295    pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
296        super::convert::from_digit(num, radix)
297    }
298
299    /// Checks if a `char` is a digit in the given radix.
300    ///
301    /// A 'radix' here is sometimes also called a 'base'. A radix of two
302    /// indicates a binary number, a radix of ten, decimal, and a radix of
303    /// sixteen, hexadecimal, to give some common values. Arbitrary
304    /// radices are supported.
305    ///
306    /// Compared to [`is_numeric()`], this function only recognizes the characters
307    /// `0-9`, `a-z` and `A-Z`.
308    ///
309    /// 'Digit' is defined to be only the following characters:
310    ///
311    /// * `0-9`
312    /// * `a-z`
313    /// * `A-Z`
314    ///
315    /// For a more comprehensive understanding of 'digit', see [`is_numeric()`].
316    ///
317    /// [`is_numeric()`]: #method.is_numeric
318    ///
319    /// # Panics
320    ///
321    /// Panics if given a radix smaller than 2 or larger than 36.
322    ///
323    /// # Examples
324    ///
325    /// Basic usage:
326    ///
327    /// ```
328    /// assert!('1'.is_digit(10));
329    /// assert!('f'.is_digit(16));
330    /// assert!(!'f'.is_digit(10));
331    /// ```
332    ///
333    /// Passing a large radix, causing a panic:
334    ///
335    /// ```should_panic
336    /// // this panics
337    /// '1'.is_digit(37);
338    /// ```
339    ///
340    /// Passing a small radix, causing a panic:
341    ///
342    /// ```should_panic
343    /// // this panics
344    /// '1'.is_digit(1);
345    /// ```
346    #[stable(feature = "rust1", since = "1.0.0")]
347    #[rustc_const_stable(feature = "const_char_classify", since = "1.87.0")]
348    #[expect(clippy::to_digit_is_some, reason = "implements is_digit")]
349    #[inline]
350    pub const fn is_digit(self, radix: u32) -> bool {
351        self.to_digit(radix).is_some()
352    }
353
354    /// Converts a `char` to a digit in the given radix.
355    ///
356    /// A 'radix' here is sometimes also called a 'base'. A radix of two
357    /// indicates a binary number, a radix of ten, decimal, and a radix of
358    /// sixteen, hexadecimal, to give some common values. Arbitrary
359    /// radices are supported.
360    ///
361    /// 'Digit' is defined to be only the following characters:
362    ///
363    /// * `0-9`
364    /// * `a-z`
365    /// * `A-Z`
366    ///
367    /// # Errors
368    ///
369    /// Returns `None` if the `char` does not refer to a digit in the given radix.
370    ///
371    /// # Panics
372    ///
373    /// Panics if given a radix smaller than 2 or larger than 36.
374    ///
375    /// # Examples
376    ///
377    /// Basic usage:
378    ///
379    /// ```
380    /// assert_eq!('1'.to_digit(10), Some(1));
381    /// assert_eq!('f'.to_digit(16), Some(15));
382    /// ```
383    ///
384    /// Passing a non-digit results in failure:
385    ///
386    /// ```
387    /// assert_eq!('f'.to_digit(10), None);
388    /// assert_eq!('z'.to_digit(16), None);
389    /// ```
390    ///
391    /// Passing a large radix, causing a panic:
392    ///
393    /// ```should_panic
394    /// // this panics
395    /// let _ = '1'.to_digit(37);
396    /// ```
397    /// Passing a small radix, causing a panic:
398    ///
399    /// ```should_panic
400    /// // this panics
401    /// let _ = '1'.to_digit(1);
402    /// ```
403    #[stable(feature = "rust1", since = "1.0.0")]
404    #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
405    #[rustc_diagnostic_item = "char_to_digit"]
406    #[must_use = "this returns the result of the operation, \
407                  without modifying the original"]
408    #[inline]
409    pub const fn to_digit(self, radix: u32) -> Option<u32> {
410        assert!(
411            radix >= 2 && radix <= 36,
412            "to_digit: invalid radix -- radix must be in the range 2 to 36 inclusive"
413        );
414        // check radix to remove letter handling code when radix is a known constant
415        let value = if self > '9' && radix > 10 {
416            // mask to convert ASCII letters to uppercase
417            const TO_UPPERCASE_MASK: u32 = !0b0010_0000;
418            // Converts an ASCII letter to its corresponding integer value:
419            // A-Z => 10-35, a-z => 10-35. Other characters produce values >= 36.
420            //
421            // Add Overflow Safety:
422            // By applying the mask after the subtraction, the first addendum is
423            // constrained such that it never exceeds u32::MAX - 0x20.
424            ((self as u32).wrapping_sub('A' as u32) & TO_UPPERCASE_MASK) + 10
425        } else {
426            // convert digit to value, non-digits wrap to values > 36
427            (self as u32).wrapping_sub('0' as u32)
428        };
429        // FIXME(const-hack): once then_some is const fn, use it here
430        if value < radix { Some(value) } else { None }
431    }
432
433    /// Returns an iterator that yields the hexadecimal Unicode escape of a
434    /// character as `char`s.
435    ///
436    /// This will escape characters with the Rust syntax of the form
437    /// `\u{NNNNNN}` where `NNNNNN` is a hexadecimal representation.
438    ///
439    /// # Examples
440    ///
441    /// As an iterator:
442    ///
443    /// ```
444    /// for c in '❤'.escape_unicode() {
445    ///     print!("{c}");
446    /// }
447    /// println!();
448    /// ```
449    ///
450    /// Using `println!` directly:
451    ///
452    /// ```
453    /// println!("{}", '❤'.escape_unicode());
454    /// ```
455    ///
456    /// Both are equivalent to:
457    ///
458    /// ```
459    /// println!("\\u{{2764}}");
460    /// ```
461    ///
462    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
463    ///
464    /// ```
465    /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
466    /// ```
467    #[must_use = "this returns the escaped char as an iterator, \
468                  without modifying the original"]
469    #[stable(feature = "rust1", since = "1.0.0")]
470    #[inline]
471    pub fn escape_unicode(self) -> EscapeUnicode {
472        EscapeUnicode::new(self)
473    }
474
475    /// An extended version of `escape_debug` that optionally permits escaping
476    /// Extended Grapheme codepoints, single quotes, and double quotes. This
477    /// allows us to format characters like nonspacing marks better when they're
478    /// at the start of a string, and allows escaping single quotes in
479    /// characters, and double quotes in strings.
480    #[inline]
481    pub(crate) fn escape_debug_ext(self, args: EscapeDebugExtArgs) -> EscapeDebug {
482        match self {
483            // Special escapes
484            '\"' if args.escape_double_quote => EscapeDebug::backslash(ascii::Char::QuotationMark),
485            '\'' if args.escape_single_quote => EscapeDebug::backslash(ascii::Char::Apostrophe),
486            '\\' => EscapeDebug::backslash(ascii::Char::ReverseSolidus),
487            '\n' => EscapeDebug::backslash(ascii::Char::SmallN),
488            '\t' => EscapeDebug::backslash(ascii::Char::SmallT),
489            '\r' => EscapeDebug::backslash(ascii::Char::SmallR),
490            '\0' => EscapeDebug::backslash(ascii::Char::Digit0),
491
492            // ASCII fast path,
493            // plus U+FF9E HALFWIDTH KATAKANA VOICED SOUND MARK
494            // and U+FF9F HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
495            // which should not be escaped despite being grapheme extenders.
496            '\x20'..='\x7E' | '\u{FF9E}' | '\u{FF9F}' => EscapeDebug::printable(self),
497
498            _ if self.is_control()
499                || self.is_private_use()
500                || self.is_whitespace()
501                || args.escape_grapheme_extender && self.is_grapheme_extender()
502                || self.is_default_ignorable()
503                || self.is_format_control()
504                || !self.is_assigned() =>
505            {
506                EscapeDebug::unicode(self)
507            }
508
509            _ => EscapeDebug::printable(self),
510        }
511    }
512
513    /// Returns an iterator that yields the literal escape code of a character
514    /// as `char`s.
515    ///
516    /// This will escape the characters similar to the [`Debug`](core::fmt::Debug) implementations
517    /// of `str` or `char`.
518    ///
519    /// # Examples
520    ///
521    /// As an iterator:
522    ///
523    /// ```
524    /// for c in '\n'.escape_debug() {
525    ///     print!("{c}");
526    /// }
527    /// println!();
528    /// ```
529    ///
530    /// Using `println!` directly:
531    ///
532    /// ```
533    /// println!("{}", '\n'.escape_debug());
534    /// ```
535    ///
536    /// Both are equivalent to:
537    ///
538    /// ```
539    /// println!("\\n");
540    /// ```
541    ///
542    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
543    ///
544    /// ```
545    /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
546    /// ```
547    #[must_use = "this returns the escaped char as an iterator, \
548                  without modifying the original"]
549    #[stable(feature = "char_escape_debug", since = "1.20.0")]
550    #[inline]
551    pub fn escape_debug(self) -> EscapeDebug {
552        self.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL)
553    }
554
555    /// Returns an iterator that yields the literal escape code of a character
556    /// as `char`s.
557    ///
558    /// The default is chosen with a bias toward producing literals that are
559    /// legal in a variety of languages, including C++11 and similar C-family
560    /// languages. The exact rules are:
561    ///
562    /// * Tab is escaped as `\t`.
563    /// * Carriage return is escaped as `\r`.
564    /// * Line feed is escaped as `\n`.
565    /// * Single quote is escaped as `\'`.
566    /// * Double quote is escaped as `\"`.
567    /// * Backslash is escaped as `\\`.
568    /// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
569    ///   inclusive is not escaped.
570    /// * All other characters are given hexadecimal Unicode escapes; see
571    ///   [`escape_unicode`].
572    ///
573    /// [`escape_unicode`]: #method.escape_unicode
574    ///
575    /// # Examples
576    ///
577    /// As an iterator:
578    ///
579    /// ```
580    /// for c in '"'.escape_default() {
581    ///     print!("{c}");
582    /// }
583    /// println!();
584    /// ```
585    ///
586    /// Using `println!` directly:
587    ///
588    /// ```
589    /// println!("{}", '"'.escape_default());
590    /// ```
591    ///
592    /// Both are equivalent to:
593    ///
594    /// ```
595    /// println!("\\\"");
596    /// ```
597    ///
598    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
599    ///
600    /// ```
601    /// assert_eq!('"'.escape_default().to_string(), "\\\"");
602    /// ```
603    #[must_use = "this returns the escaped char as an iterator, \
604                  without modifying the original"]
605    #[stable(feature = "rust1", since = "1.0.0")]
606    #[inline]
607    pub fn escape_default(self) -> EscapeDefault {
608        match self {
609            '\t' => EscapeDefault::backslash(ascii::Char::SmallT),
610            '\r' => EscapeDefault::backslash(ascii::Char::SmallR),
611            '\n' => EscapeDefault::backslash(ascii::Char::SmallN),
612            '\\' | '\'' | '\"' => EscapeDefault::backslash(self.as_ascii().unwrap()),
613            '\x20'..='\x7e' => EscapeDefault::printable(self.as_ascii().unwrap()),
614            _ => EscapeDefault::unicode(self),
615        }
616    }
617
618    /// Returns the number of bytes this `char` would need if encoded in UTF-8.
619    ///
620    /// That number of bytes is always between 1 and 4, inclusive.
621    ///
622    /// # Examples
623    ///
624    /// Basic usage:
625    ///
626    /// ```
627    /// let len = 'A'.len_utf8();
628    /// assert_eq!(len, 1);
629    ///
630    /// let len = 'ß'.len_utf8();
631    /// assert_eq!(len, 2);
632    ///
633    /// let len = 'ℝ'.len_utf8();
634    /// assert_eq!(len, 3);
635    ///
636    /// let len = '💣'.len_utf8();
637    /// assert_eq!(len, 4);
638    /// ```
639    ///
640    /// The `&str` type guarantees that its contents are UTF-8, and so we can compare the length it
641    /// would take if each code point was represented as a `char` vs in the `&str` itself:
642    ///
643    /// ```
644    /// // as chars
645    /// let eastern = '東';
646    /// let capital = '京';
647    ///
648    /// // both can be represented as three bytes
649    /// assert_eq!(3, eastern.len_utf8());
650    /// assert_eq!(3, capital.len_utf8());
651    ///
652    /// // as a &str, these two are encoded in UTF-8
653    /// let tokyo = "東京";
654    ///
655    /// let len = eastern.len_utf8() + capital.len_utf8();
656    ///
657    /// // we can see that they take six bytes total...
658    /// assert_eq!(6, tokyo.len());
659    ///
660    /// // ... just like the &str
661    /// assert_eq!(len, tokyo.len());
662    /// ```
663    #[stable(feature = "rust1", since = "1.0.0")]
664    #[rustc_const_stable(feature = "const_char_len_utf", since = "1.52.0")]
665    #[inline]
666    #[must_use]
667    pub const fn len_utf8(self) -> usize {
668        len_utf8(self as u32)
669    }
670
671    /// Returns the number of 16-bit code units this `char` would need if
672    /// encoded in UTF-16.
673    ///
674    /// That number of code units is always either 1 or 2, for unicode scalar values in
675    /// the [basic multilingual plane] or [supplementary planes] respectively.
676    ///
677    /// See the documentation for [`len_utf8()`] for more explanation of this
678    /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
679    ///
680    /// [basic multilingual plane]: http://www.unicode.org/glossary/#basic_multilingual_plane
681    /// [supplementary planes]: http://www.unicode.org/glossary/#supplementary_planes
682    /// [`len_utf8()`]: #method.len_utf8
683    ///
684    /// # Examples
685    ///
686    /// Basic usage:
687    ///
688    /// ```
689    /// let n = 'ß'.len_utf16();
690    /// assert_eq!(n, 1);
691    ///
692    /// let len = '💣'.len_utf16();
693    /// assert_eq!(len, 2);
694    /// ```
695    #[stable(feature = "rust1", since = "1.0.0")]
696    #[rustc_const_stable(feature = "const_char_len_utf", since = "1.52.0")]
697    #[inline]
698    #[must_use]
699    pub const fn len_utf16(self) -> usize {
700        len_utf16(self as u32)
701    }
702
703    /// Encodes this character as UTF-8 into the provided byte buffer,
704    /// and then returns the subslice of the buffer that contains the encoded character.
705    ///
706    /// # Panics
707    ///
708    /// Panics if the buffer is not large enough.
709    /// A buffer of length four is large enough to encode any `char`.
710    ///
711    /// # Examples
712    ///
713    /// In both of these examples, 'ß' takes two bytes to encode.
714    ///
715    /// ```
716    /// let mut b = [0; 2];
717    ///
718    /// let result = 'ß'.encode_utf8(&mut b);
719    ///
720    /// assert_eq!(result, "ß");
721    ///
722    /// assert_eq!(result.len(), 2);
723    /// ```
724    ///
725    /// A buffer that's too small:
726    ///
727    /// ```should_panic
728    /// let mut b = [0; 1];
729    ///
730    /// // this panics
731    /// 'ß'.encode_utf8(&mut b);
732    /// ```
733    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
734    #[rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0")]
735    #[inline]
736    pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
737        // SAFETY: `char` is not a surrogate, so this is valid UTF-8.
738        unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
739    }
740
741    /// Encodes this character as native endian UTF-16 into the provided `u16` buffer,
742    /// and then returns the subslice of the buffer that contains the encoded character.
743    ///
744    /// # Panics
745    ///
746    /// Panics if the buffer is not large enough.
747    /// A buffer of length 2 is large enough to encode any `char`.
748    ///
749    /// # Examples
750    ///
751    /// In both of these examples, '𝕊' takes two `u16`s to encode.
752    ///
753    /// ```
754    /// let mut b = [0; 2];
755    ///
756    /// let result = '𝕊'.encode_utf16(&mut b);
757    ///
758    /// assert_eq!(result.len(), 2);
759    /// ```
760    ///
761    /// A buffer that's too small:
762    ///
763    /// ```should_panic
764    /// let mut b = [0; 1];
765    ///
766    /// // this panics
767    /// '𝕊'.encode_utf16(&mut b);
768    /// ```
769    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
770    #[rustc_const_stable(feature = "const_char_encode_utf16", since = "1.84.0")]
771    #[inline]
772    pub const fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
773        encode_utf16_raw(self as u32, dst)
774    }
775
776    /// Returns `true` if this `char` has the `Alphabetic` property.
777    ///
778    /// `Alphabetic` is [described] in Chapter 4 (Character Properties) of the Unicode Standard, and
779    /// [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
780    ///
781    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G32524
782    /// [specified]: https://www.unicode.org/reports/tr44/#Alphabetic
783    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
784    ///
785    /// # Examples
786    ///
787    /// Basic usage:
788    ///
789    /// ```
790    /// assert!('a'.is_alphabetic());
791    /// assert!('京'.is_alphabetic());
792    ///
793    /// let c = '💝';
794    /// // love is many things, but it is not alphabetic
795    /// assert!(!c.is_alphabetic());
796    /// ```
797    #[must_use]
798    #[stable(feature = "rust1", since = "1.0.0")]
799    #[inline]
800    pub fn is_alphabetic(self) -> bool {
801        match self {
802            'a'..='z' | 'A'..='Z' => true,
803            '\0'..='\u{A9}' => false,
804            _ => unicode::Alphabetic(self),
805        }
806    }
807
808    /// Returns `true` if this `char` has the `Cased` property.
809    /// A character is cased if and only if it is uppercase, lowercase, or titlecase.
810    ///
811    /// `Cased` is [described] in Chapter 3 (Character Properties) of the Unicode Standard and
812    /// [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
813    ///
814    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-3/#G44595
815    /// [specified]: https://www.unicode.org/reports/tr44/#Cased
816    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
817    ///
818    /// # Examples
819    ///
820    /// Basic usage:
821    ///
822    /// ```
823    /// #![feature(titlecase)]
824    /// assert!('A'.is_cased());
825    /// assert!('a'.is_cased());
826    /// assert!(!'京'.is_cased());
827    /// ```
828    #[must_use]
829    #[unstable(feature = "titlecase", issue = "153892")]
830    #[inline]
831    pub fn is_cased(self) -> bool {
832        match self {
833            'a'..='z' | 'A'..='Z' => true,
834            '\0'..='\u{A9}' => false,
835            _ => unicode::Lowercase(self) || unicode::Uppercase(self) || unicode::Lt(self),
836        }
837    }
838
839    /// Returns the case of this character:
840    /// [`Some(CharCase::Upper)`][`CharCase::Upper`] if [`self.is_uppercase()`][`char::is_uppercase`],
841    /// [`Some(CharCase::Lower)`][`CharCase::Lower`] if [`self.is_lowercase()`][`char::is_lowercase`],
842    /// [`Some(CharCase::Title)`][`CharCase::Title`] if [`self.is_titlecase()`][`char::is_titlecase`], and
843    /// `None` if [`!self.is_cased()`][`char::is_cased`].
844    ///
845    /// # Examples
846    ///
847    /// ```
848    /// #![feature(titlecase)]
849    /// use core::char::CharCase;
850    /// assert_eq!('a'.case(), Some(CharCase::Lower));
851    /// assert_eq!('δ'.case(), Some(CharCase::Lower));
852    /// assert_eq!('A'.case(), Some(CharCase::Upper));
853    /// assert_eq!('Δ'.case(), Some(CharCase::Upper));
854    /// assert_eq!('Dž'.case(), Some(CharCase::Title));
855    /// assert_eq!('中'.case(), None);
856    /// ```
857    #[must_use]
858    #[unstable(feature = "titlecase", issue = "153892")]
859    #[inline]
860    pub fn case(self) -> Option<CharCase> {
861        match self {
862            'a'..='z' => Some(CharCase::Lower),
863            'A'..='Z' => Some(CharCase::Upper),
864            '\0'..='\u{A9}' => None,
865            _ if unicode::Lowercase(self) => Some(CharCase::Lower),
866            _ if unicode::Uppercase(self) => Some(CharCase::Upper),
867            _ if unicode::Lt(self) => Some(CharCase::Title),
868            _ => None,
869        }
870    }
871
872    /// Returns `true` if this `char` has the `Lowercase` property.
873    ///
874    /// `Lowercase` is [described] in Chapter 4 (Character Properties) of the Unicode Standard, and
875    /// [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
876    ///
877    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G136255
878    /// [specified]: https://www.unicode.org/reports/tr44/#Lowercase
879    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
880    ///
881    /// # Examples
882    ///
883    /// Basic usage:
884    ///
885    /// ```
886    /// assert!('a'.is_lowercase());
887    /// assert!('δ'.is_lowercase());
888    /// assert!(!'A'.is_lowercase());
889    /// assert!(!'Δ'.is_lowercase());
890    ///
891    /// // The various Chinese scripts and punctuation do not have case, and so:
892    /// assert!(!'中'.is_lowercase());
893    /// assert!(!' '.is_lowercase());
894    /// ```
895    ///
896    /// In a const context:
897    ///
898    /// ```
899    /// const CAPITAL_DELTA_IS_LOWERCASE: bool = 'Δ'.is_lowercase();
900    /// assert!(!CAPITAL_DELTA_IS_LOWERCASE);
901    /// ```
902    #[must_use]
903    #[stable(feature = "rust1", since = "1.0.0")]
904    #[rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0")]
905    #[inline]
906    pub const fn is_lowercase(self) -> bool {
907        match self {
908            'a'..='z' => true,
909            '\0'..='\u{A9}' => false,
910            _ => unicode::Lowercase(self),
911        }
912    }
913
914    /// Returns `true` if this `char` is in the general category for titlecase letters.
915    /// Conceptually, these characters consist of an uppercase portion followed by a lowercase portion.
916    ///
917    /// Titlecase letters (code points with the general category of `Lt`) are [described] in Chapter 4
918    /// (Character Properties) of the Unicode Standard, and [specified] in the Unicode Character
919    /// Database [`UnicodeData.txt`].
920    ///
921    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G124722
922    /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
923    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
924    ///
925    /// # Examples
926    ///
927    /// Basic usage:
928    ///
929    /// ```
930    /// #![feature(titlecase)]
931    /// assert!('Dž'.is_titlecase());
932    /// assert!('ῼ'.is_titlecase());
933    /// assert!(!'D'.is_titlecase());
934    /// assert!(!'z'.is_titlecase());
935    /// assert!(!'中'.is_titlecase());
936    /// assert!(!' '.is_titlecase());
937    /// ```
938    #[must_use]
939    #[unstable(feature = "titlecase", issue = "153892")]
940    #[inline]
941    pub fn is_titlecase(self) -> bool {
942        match self {
943            '\0'..='\u{01C4}' => false,
944            _ => unicode::Lt(self),
945        }
946    }
947
948    /// Returns `true` if this `char` has the `Uppercase` property.
949    ///
950    /// `Uppercase` is [described] in Chapter 4 (Character Properties) of the Unicode Standard, and
951    /// [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
952    ///
953    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G136255
954    /// [specified]: https://www.unicode.org/reports/tr44/#Uppercase
955    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
956    ///
957    /// # Examples
958    ///
959    /// Basic usage:
960    ///
961    /// ```
962    /// assert!(!'a'.is_uppercase());
963    /// assert!(!'δ'.is_uppercase());
964    /// assert!('A'.is_uppercase());
965    /// assert!('Δ'.is_uppercase());
966    ///
967    /// // The various Chinese scripts and punctuation do not have case, and so:
968    /// assert!(!'中'.is_uppercase());
969    /// assert!(!' '.is_uppercase());
970    /// ```
971    ///
972    /// In a const context:
973    ///
974    /// ```
975    /// const CAPITAL_DELTA_IS_UPPERCASE: bool = 'Δ'.is_uppercase();
976    /// assert!(CAPITAL_DELTA_IS_UPPERCASE);
977    /// ```
978    #[must_use]
979    #[stable(feature = "rust1", since = "1.0.0")]
980    #[rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0")]
981    #[inline]
982    pub const fn is_uppercase(self) -> bool {
983        match self {
984            'A'..='Z' => true,
985            '\0'..='\u{BF}' => false,
986            _ => unicode::Uppercase(self),
987        }
988    }
989
990    /// Returns `true` if this `char` has one of the general categories for numbers.
991    ///
992    /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
993    /// characters, and `No` for other numeric characters) are [specified] in the Unicode Character
994    /// Database [`UnicodeData.txt`].
995    ///
996    /// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'.
997    /// If you want everything including characters with overlapping purposes, then you might want to use
998    /// a Unicode or language-processing library that exposes the appropriate character properties
999    /// (e.g. [`Numeric_Type`]) instead of looking at the Unicode categories.
1000    ///
1001    /// If you want to parse ASCII decimal digits (0-9) or ASCII base-N, use
1002    /// `is_ascii_digit` or `is_digit` instead.
1003    ///
1004    /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
1005    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1006    /// [`Numeric_Type`]: https://www.unicode.org/reports/tr44/#Numeric_Type
1007    ///
1008    /// # Examples
1009    ///
1010    /// Basic usage:
1011    ///
1012    /// ```
1013    /// assert!('٣'.is_numeric());
1014    /// assert!('7'.is_numeric());
1015    /// assert!('৬'.is_numeric());
1016    /// assert!('¾'.is_numeric());
1017    /// assert!('①'.is_numeric());
1018    /// assert!(!'K'.is_numeric());
1019    /// assert!(!'و'.is_numeric());
1020    /// assert!(!'藏'.is_numeric());
1021    /// assert!(!'三'.is_numeric());
1022    /// ```
1023    #[must_use]
1024    #[stable(feature = "rust1", since = "1.0.0")]
1025    #[inline]
1026    pub fn is_numeric(self) -> bool {
1027        match self {
1028            '0'..='9' => true,
1029            '\0'..='\u{B1}' => false,
1030            _ => unicode::N(self),
1031        }
1032    }
1033
1034    /// Returns `true` if this `char` satisfies either [`is_alphabetic()`] or [`is_numeric()`].
1035    ///
1036    /// [`is_alphabetic()`]: Self::is_alphabetic
1037    /// [`is_numeric()`]: Self::is_numeric
1038    ///
1039    /// # Examples
1040    ///
1041    /// Basic usage:
1042    ///
1043    /// ```
1044    /// assert!('٣'.is_alphanumeric());
1045    /// assert!('7'.is_alphanumeric());
1046    /// assert!('৬'.is_alphanumeric());
1047    /// assert!('¾'.is_alphanumeric());
1048    /// assert!('①'.is_alphanumeric());
1049    /// assert!('K'.is_alphanumeric());
1050    /// assert!('و'.is_alphanumeric());
1051    /// assert!('藏'.is_alphanumeric());
1052    /// ```
1053    #[must_use]
1054    #[stable(feature = "rust1", since = "1.0.0")]
1055    #[inline]
1056    pub fn is_alphanumeric(self) -> bool {
1057        match self {
1058            'a'..='z' | 'A'..='Z' | '0'..='9' => true,
1059            '\0'..='\u{A9}' => false,
1060            _ => unicode::Alphabetic(self) || unicode::N(self),
1061        }
1062    }
1063
1064    /// Returns `true` if this `char` has the `White_Space` property.
1065    ///
1066    /// `White_Space` is [specified] in the Unicode Character Database [`PropList.txt`].
1067    ///
1068    /// [specified]: https://www.unicode.org/reports/tr44/#White_Space
1069    /// [`PropList.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
1070    ///
1071    /// # Examples
1072    ///
1073    /// Basic usage:
1074    ///
1075    /// ```
1076    /// assert!(' '.is_whitespace());
1077    ///
1078    /// // line break
1079    /// assert!('\n'.is_whitespace());
1080    ///
1081    /// // a non-breaking space
1082    /// assert!('\u{A0}'.is_whitespace());
1083    ///
1084    /// assert!(!'越'.is_whitespace());
1085    /// ```
1086    #[must_use]
1087    #[stable(feature = "rust1", since = "1.0.0")]
1088    #[rustc_const_stable(feature = "const_char_classify", since = "1.87.0")]
1089    #[inline]
1090    pub const fn is_whitespace(self) -> bool {
1091        match self {
1092            ' ' | '\x09'..='\x0d' => true,
1093            '\0'..='\u{84}' => false,
1094            _ => unicode::White_Space(self),
1095        }
1096    }
1097
1098    /// Returns `true` if this `char` has the general category for control codes.
1099    ///
1100    /// Control codes (code points with the general category of `Cc`) are [described] in Chapter 23
1101    /// (Special Areas and Format Characters) of the Unicode Standard, and [specified] in the Unicode Character
1102    /// Database [`UnicodeData.txt`]. The full set of Unicode control codes is
1103    /// `'\0'..='\x1f' | '\x7f'..='\u{9f}'`, and will never change.
1104    ///
1105    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-23/#G20365
1106    /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
1107    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1108    ///
1109    /// # Examples
1110    ///
1111    /// Basic usage:
1112    ///
1113    /// ```
1114    /// assert!('\t'.is_control());
1115    /// assert!('\n'.is_control());
1116    /// assert!('\u{9C}'.is_control()); // STRING TERMINATOR
1117    /// assert!(!'q'.is_control());
1118    /// ```
1119    #[must_use]
1120    #[stable(feature = "rust1", since = "1.0.0")]
1121    #[rustc_const_stable(feature = "const_is_control", since = "1.97.0")]
1122    #[inline]
1123    pub const fn is_control(self) -> bool {
1124        // According to
1125        // https://www.unicode.org/policies/stability_policy.html#Property_Value,
1126        // the set of codepoints in `Cc` will never change.
1127        // So we can just hard-code the patterns to match against instead of using a table.
1128        matches!(self, '\0'..='\x1f' | '\x7f'..='\u{9f}')
1129    }
1130
1131    /// Returns `true` if this `char` has the general category for [private-use characters].
1132    /// These characters do not have an interpretation specified by Unicode; individual programs
1133    /// and users are free to assign them whatever meaning they like.
1134    ///
1135    /// [private-use characters]: https://www.unicode.org/faq/private_use#private_use
1136    ///
1137    /// Private-use characters (code points with the general category of `Co`) are [described] in Chapter 23
1138    /// (Special Areas and Format Characters) of the Unicode Standard, and [specified] in the
1139    /// Unicode Character Database [`UnicodeData.txt`]. The full set of private-use characters is
1140    /// `'\u{E000}'..='\u{F8FF}' | '\u{F0000}'..='\u{FFFFD}' | '\u{100000}'..='\u{10FFFD}'`,
1141    /// and will never change.
1142    ///
1143    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-23/#G19184
1144    /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
1145    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1146    ///
1147    #[must_use]
1148    #[unstable(feature = "char_unassigned_private_use", issue = "158322")]
1149    #[inline]
1150    pub const fn is_private_use(self) -> bool {
1151        // According to
1152        // https://www.unicode.org/policies/stability_policy.html#Property_Value,
1153        // the set of codepoints in `Co` will never change.
1154        // So we can just hard-code the patterns to match against instead of using a table.
1155        matches!(self, '\u{E000}'..='\u{F8FF}' | '\u{F0000}'..='\u{FFFFD}' | '\u{100000}'..='\u{10FFFD}')
1156    }
1157
1158    /// Returns `true` if this `char` has the general category for format control characters.
1159    ///
1160    /// Format controls (code points with the general category of `Cf`) are [described] in Chapter 4
1161    /// (Character Properties) of the Unicode Standard, and [specified] in the Unicode Character
1162    /// Database [`UnicodeData.txt`].
1163    ///
1164    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
1165    /// [specified]: https://www.unicode.org/reports/tr44/#GC_Values_Table
1166    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1167    ///
1168    /// # Examples
1169    ///
1170    /// Basic usage:
1171    ///
1172    /// ```ignore(private)
1173    /// assert!('\u{AD}'.is_format_control()); // SOFT HYPHEN
1174    /// assert!('\u{200B}'.is_format_control()); // ZERO WIDTH SPACE
1175    /// assert!('\u{E0041}'.is_format_control()); // TAG LATIN CAPITAL LETTER A
1176    /// assert!('۝'.is_format_control()); // ARABIC END OF AYAH
1177    /// assert!('𓐲'.is_format_control()); // EGYPTIAN HIEROGLYPH INSERT AT TOP START
1178    /// assert!(!'q'.is_format_control());
1179    /// ```
1180    #[must_use]
1181    #[inline]
1182    fn is_format_control(self) -> bool {
1183        self > '\u{AC}' && unicode::Cf(self)
1184    }
1185
1186    /// Returns `true` if this `char` has been assigned a meaning by Unicode, as of
1187    /// [`UNICODE_VERSION`].
1188    ///
1189    /// [`UNICODE_VERSION`]: Self::UNICODE_VERSION
1190    ///
1191    /// Many of Unicode's [stability policies] apply only to assigned characters.
1192    ///
1193    /// [stability policies]: https://www.unicode.org/policies/stability_policy.html
1194    ///
1195    /// Currently unassigned characters (characters for which this method returns `false`)
1196    /// may have a meaning assigned in a future version of Unicode,
1197    /// except for the 66 [noncharacters] which will never be assigned a meaning.
1198    ///
1199    /// [noncharacters]: https://www.unicode.org/faq/private_use.html#noncharacters
1200    ///
1201    /// A character is considered assigned if it is present in [`UnicodeData.txt`].
1202    /// Unassigned characters have general category `Cn`, as [described] in Chapter 4
1203    /// (Character Properties) of the Unicode Standard.
1204    ///
1205    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1206    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
1207    ///
1208    /// # Examples
1209    ///
1210    /// Basic usage:
1211    ///
1212    /// ```
1213    /// #![feature(char_unassigned_private_use)]
1214    /// assert!('γ'.is_assigned()); // once a character is assigned, it stays assigned forever
1215    /// assert!(!'\u{FFFE}'.is_assigned()); // noncharacter, will never be assigned
1216    ///
1217    /// // Not currently assigned, but may be in the future,
1218    /// // so we shouldn't rely on the current status
1219    /// /* assert!(!'\u{7AAAA}'.is_assigned()); */
1220    /// ```
1221    #[must_use]
1222    #[unstable(feature = "char_unassigned_private_use", issue = "158322")]
1223    #[inline]
1224    pub fn is_assigned(self) -> bool {
1225        match self {
1226            '\0'..='\u{377}' => true,
1227            '\u{378}'..='\u{3FFFD}' => !unicode::Cn_planes_0_3(self),
1228            // Assigned character ranges in planes 4 and above.
1229            // `src/tools/unicode-table-generator/src/main.rs` asserts that this is correct
1230            '\u{E0001}'
1231            | '\u{E0020}'..='\u{E007F}'
1232            | '\u{E0100}'..='\u{E01EF}'
1233            | '\u{F0000}'..='\u{FFFFD}'
1234            | '\u{100000}'..='\u{10FFFD}' => true,
1235            _ => false,
1236        }
1237    }
1238
1239    /// Returns `true` if this `char` has the `Default_Ignorable_Code_Point` property.
1240    /// These characters [should be displayed as invisible in fallback rendering](https://www.unicode.org/faq/unsup_char#3).
1241    ///
1242    /// `Default_Ignorable_Code_Point` is [described] in Chapter 5 (Implementation Guidelines) of the Unicode Standard,
1243    /// and [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
1244    ///
1245    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-5/#G40120
1246    /// [specified]: https://www.unicode.org/reports/tr44/#Default_Ignorable_Code_Point
1247    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
1248    ///
1249    /// # Examples
1250    ///
1251    /// Basic usage:
1252    ///
1253    /// ```
1254    /// #![feature(default_ignorable)]
1255    /// assert!('\u{AD}'.is_default_ignorable()); // SOFT HYPHEN
1256    /// assert!('\u{115F}'.is_default_ignorable()); // HANGUL CHOSEONG FILLER
1257    /// assert!('\u{200B}'.is_default_ignorable()); // ZERO WIDTH SPACE
1258    /// assert!('\u{E0041}'.is_default_ignorable()); // TAG LATIN CAPITAL LETTER A
1259    /// assert!(!'۝'.is_default_ignorable()); // ARABIC END OF AYAH
1260    /// assert!(!'𓐲'.is_default_ignorable()); // EGYPTIAN HIEROGLYPH INSERT AT TOP START
1261    /// assert!(!' '.is_default_ignorable());
1262    /// assert!(!'\n'.is_default_ignorable());
1263    /// assert!(!'\0'.is_default_ignorable());
1264    /// assert!(!'q'.is_default_ignorable());
1265    /// ```
1266    #[must_use]
1267    #[unstable(feature = "default_ignorable", issue = "160583")]
1268    #[inline]
1269    pub fn is_default_ignorable(self) -> bool {
1270        self > '\u{AC}' && unicode::Default_Ignorable_Code_Point(self)
1271    }
1272
1273    /// Returns `true` if this `char` has the `Grapheme_Extend` property.
1274    ///
1275    /// `Grapheme_Extend` is [described] in Chapter 3 (Conformance) of the Unicode Standard,
1276    /// and [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
1277    ///
1278    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-3/#G41165
1279    /// [specified]: https://www.unicode.org/reports/tr44/#Grapheme_Extend
1280    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
1281    #[must_use]
1282    #[inline]
1283    fn is_grapheme_extender(self) -> bool {
1284        self > '\u{02FF}' && unicode::Grapheme_Extend(self)
1285    }
1286
1287    /// Returns `true` if this `char` has the `Case_Ignorable` property. This narrow-use property
1288    /// is used to implement context-dependent casing for the Greek letter sigma (uppercase 'Σ'),
1289    /// which has two lowercase forms.
1290    ///
1291    /// `Case_Ignorable` is [described] in Chapter 3 (Conformance) of the Unicode Core Specification,
1292    /// and [specified] in the Unicode Character Database [`DerivedCoreProperties.txt`].
1293    /// See those resources, as well as [`to_lowercase()`]'s documentation, for more information.
1294    ///
1295    /// [described]: https://www.unicode.org/versions/latest/core-spec/chapter-3/#G63116
1296    /// [specified]: https://www.unicode.org/reports/tr44/#Case_Ignorable
1297    /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
1298    /// [`to_lowercase()`]: Self::to_lowercase()
1299    #[must_use]
1300    #[inline]
1301    #[unstable(feature = "case_ignorable", issue = "154848")]
1302    pub fn is_case_ignorable(self) -> bool {
1303        if self.is_ascii() {
1304            matches!(self, '\'' | '.' | ':' | '^' | '`')
1305        } else {
1306            unicode::Case_Ignorable(self)
1307        }
1308    }
1309
1310    /// Returns an iterator that yields the lowercase mapping of this `char` as one or more
1311    /// `char`s.
1312    ///
1313    /// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
1314    ///
1315    /// If this `char` has a one-to-one lowercase mapping given by the [Unicode Character
1316    /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
1317    ///
1318    /// [ucd]: https://www.unicode.org/reports/tr44/
1319    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1320    ///
1321    /// If this `char` expands to multiple `char`s, the iterator yields the `char`s given by
1322    /// [`SpecialCasing.txt`]. The maximum number of `char`s in a case mapping is 3.
1323    ///
1324    /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1325    /// is independent of context and language. See [below](#notes-on-context-and-locale)
1326    /// for more information.
1327    ///
1328    /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1329    /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1330    ///
1331    /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1332    ///
1333    /// # Examples
1334    ///
1335    /// As an iterator:
1336    ///
1337    /// ```
1338    /// for c in 'İ'.to_lowercase() {
1339    ///     print!("{c}");
1340    /// }
1341    /// println!();
1342    /// ```
1343    ///
1344    /// Using `println!` directly:
1345    ///
1346    /// ```
1347    /// println!("{}", 'İ'.to_lowercase());
1348    /// ```
1349    ///
1350    /// Both are equivalent to:
1351    ///
1352    /// ```
1353    /// println!("i\u{307}");
1354    /// ```
1355    ///
1356    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1357    ///
1358    /// ```
1359    /// assert_eq!('C'.to_lowercase().to_string(), "c");
1360    ///
1361    /// // Sometimes the result is more than one character:
1362    /// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
1363    ///
1364    /// // Characters that do not have both uppercase and lowercase
1365    /// // convert into themselves.
1366    /// assert_eq!('山'.to_lowercase().to_string(), "山");
1367    /// ```
1368    /// # Notes on context and locale
1369    ///
1370    /// As stated earlier, this method does not take into account language or context.
1371    /// Below is a non-exhaustive list of situations where this can be relevant.
1372    /// If you need to handle locale-depedendent casing in your code, consider using
1373    /// an external crate, like [`icu_casemap`](https://crates.io/crates/icu_casemap)
1374    /// which is developed by Unicode.
1375    ///
1376    /// ## Greek sigma
1377    ///
1378    /// In Greek, the letter simga (uppercase 'Σ') has two lowercase forms:
1379    /// 'σ' which is used in most situations, and 'ς' which appears only
1380    /// at the end of a word. [`char::to_lowercase()`] always uses the first form:
1381    ///
1382    /// ```
1383    /// assert_eq!('Σ'.to_lowercase().to_string(), "σ");
1384    /// ```
1385    ///
1386    /// `str::to_lowercase()` (only available with the `alloc` crate)
1387    /// *does* properly handle this contextual mapping,
1388    /// so prefer using that method if you can. Alternatively, you can use
1389    /// [`is_cased()`] and [`is_case_ignorable()`] to implement it yourself.
1390    /// See `Final_Sigma` in [Table 3.17] of the Unicode Standard,
1391    /// along with [`SpecialCasing.txt`], for more details.
1392    ///
1393    /// [`is_cased()`]: Self::is_cased()
1394    /// [`is_case_ignorable()`]: Self::is_case_ignorable()
1395    /// [Table 3.17]: https://www.unicode.org/versions/latest/core-spec/chapter-3/#G54277
1396    ///
1397    /// ## Turkish and Azeri I/ı/İ/i
1398    ///
1399    /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
1400    ///
1401    /// * 'Dotless': I / ı, sometimes written ï
1402    /// * 'Dotted': İ / i
1403    ///
1404    /// Note that the uppercase undotted 'I' is the same codepoint as the Latin. Therefore:
1405    ///
1406    /// ```
1407    /// let lower_i = 'I'.to_lowercase().to_string();
1408    /// ```
1409    ///
1410    /// `'I'`'s correct lowercase relies on the language of the text: if we're
1411    /// in `en-US`, it should be `"i"`, but if we're in `tr-TR` or `az-AZ`, it should
1412    /// be `"ı"`. `to_lowercase()` does not take this into account, and so:
1413    ///
1414    /// ```
1415    /// let lower_i = 'I'.to_lowercase().to_string();
1416    ///
1417    /// assert_eq!(lower_i, "i");
1418    /// ```
1419    ///
1420    /// holds across languages.
1421    ///
1422    /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
1423    #[must_use = "this returns the lowercased character as a new iterator, \
1424                  without modifying the original"]
1425    #[stable(feature = "rust1", since = "1.0.0")]
1426    #[inline]
1427    pub fn to_lowercase(self) -> ToLowercase {
1428        ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
1429    }
1430
1431    /// Returns an iterator that yields the titlecase mapping of this `char` as one or more
1432    /// `char`s.
1433    ///
1434    /// This is usually, but not always, equivalent to the uppercase mapping
1435    /// returned by [`to_uppercase()`]. Prefer this method when seeking to capitalize
1436    /// Only The First Letter of a word, but use [`to_uppercase()`] for ALL CAPS.
1437    /// See [below](#difference-from-uppercase) for a thorough explanation
1438    /// of the difference between the two methods.
1439    ///
1440    /// If this `char` does not have a titlecase mapping, the iterator yields the same `char`.
1441    ///
1442    /// If this `char` has a one-to-one titlecase mapping given by the [Unicode Character
1443    /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
1444    ///
1445    /// [ucd]: https://www.unicode.org/reports/tr44/
1446    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1447    ///
1448    /// If this `char` expands to multiple `char`s, the iterator yields the `char`s given by
1449    /// [`SpecialCasing.txt`]. The maximum number of `char`s in a case mapping is 3.
1450    ///
1451    /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
1452    ///
1453    /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1454    /// is independent of context and language. See [below](#note-on-locale)
1455    /// for more information.
1456    ///
1457    /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1458    /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1459    ///
1460    /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1461    ///
1462    /// # Examples
1463    ///
1464    /// As an iterator:
1465    ///
1466    /// ```
1467    /// #![feature(titlecase)]
1468    /// for c in 'ß'.to_titlecase() {
1469    ///     print!("{c}");
1470    /// }
1471    /// println!();
1472    /// ```
1473    ///
1474    /// Using `println!` directly:
1475    ///
1476    /// ```
1477    /// #![feature(titlecase)]
1478    /// println!("{}", 'ß'.to_titlecase());
1479    /// ```
1480    ///
1481    /// Both are equivalent to:
1482    ///
1483    /// ```
1484    /// println!("Ss");
1485    /// ```
1486    ///
1487    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1488    ///
1489    /// ```
1490    /// #![feature(titlecase)]
1491    /// assert_eq!('c'.to_titlecase().to_string(), "C");
1492    /// assert_eq!('ა'.to_titlecase().to_string(), "ა");
1493    /// assert_eq!('dž'.to_titlecase().to_string(), "Dž");
1494    /// assert_eq!('ᾨ'.to_titlecase().to_string(), "ᾨ");
1495    ///
1496    /// // Sometimes the result is more than one character:
1497    /// assert_eq!('ß'.to_titlecase().to_string(), "Ss");
1498    ///
1499    /// // Characters that do not have separate cased forms
1500    /// // convert into themselves.
1501    /// assert_eq!('山'.to_titlecase().to_string(), "山");
1502    /// ```
1503    ///
1504    /// # Difference from uppercase
1505    ///
1506    /// Currently, there are three classes of characters where [`to_uppercase()`]
1507    /// and `to_titlecase()` give different results:
1508    ///
1509    /// ## Georgian script
1510    ///
1511    /// Each letter in the modern Georgian alphabet can be written in one of two forms:
1512    /// the typical lowercase-like "mkhedruli" form, and a variant uppercase-like "mtavruli"
1513    /// form. However, unlike uppercase in most cased scripts, mtavruli is not typically used
1514    /// to start sentences, denote proper nouns, or for any other purpose
1515    /// in running text. It is instead confined to titles and headings, which are written entirely
1516    /// in mtavruli. For this reason, [`to_uppercase()`] applied to a Georgian letter
1517    /// will return the mtavruli form, but `to_titlecase()` will return the mkhedruli form.
1518    ///
1519    /// ```
1520    /// #![feature(titlecase)]
1521    /// let ani = 'ა'; // First letter of the Georgian alphabet, in mkhedruli form
1522    ///
1523    /// // Titlecasing mkhedruli maps it to itself...
1524    /// assert_eq!(ani.to_titlecase().to_string(), ani.to_string());
1525    ///
1526    /// // but uppercasing it maps it to mtavruli
1527    /// assert_eq!(ani.to_uppercase().to_string(), "Ა");
1528    /// ```
1529    ///
1530    /// ## Compatibility digraphs for Latin-alphabet Serbo-Croatian
1531    ///
1532    /// The standard Latin alphabet for the Serbo-Croatian language
1533    /// (Bosnian, Croatian, Montenegrin, and Serbian) contains
1534    /// three digraphs: Dž, Lj, and Nj. These are usually represented as
1535    /// two characters. However, for compatibility with older character sets,
1536    /// Unicode includes single-character versions of these digraphs.
1537    /// Each has a uppercase, titlecase, and lowercase version:
1538    ///
1539    /// - `'DŽ'`, `'Dž'`, `'dž'`
1540    /// - `'LJ'`, `'Lj'`, `'lj'`
1541    /// - `'NJ'`, `'Nj'`, `'nj'`
1542    ///
1543    /// Unicode additionally encodes a casing triad for the Dz digraph
1544    /// without the caron: `'DZ'`, `'Dz'`, `'dz'`.
1545    ///
1546    /// ## Iota-subscritped Greek vowels
1547    ///
1548    /// In ancient Greek, the long vowels alpha (α), eta (η), and omega (ω)
1549    /// were sometimes followed by an iota (ι), forming a diphthong. Over time,
1550    /// the diphthong pronunciation was slowly lost, with the iota becoming mute.
1551    /// Eventually, the ι disappeared from the spelling as well.
1552    /// However, there remains a need to represent ancient texts faithfully.
1553    ///
1554    /// Modern editions of ancient Greek texts commonly use a reduced-sized
1555    /// ι symbol to denote mute iotas, while distinguishing them from ιs
1556    /// which continued to affect pronunciation. The exact standard differs
1557    /// between different publications. Some render the mute ι below its associated
1558    /// vowel (subscript), while others place it to the right of said vowel (adscript).
1559    /// The interaction of mute ι symbols with casing also varies.
1560    ///
1561    /// The Unicode Standard, for its default casing rules, chose to make lowercase
1562    /// Greek vowels with iota subscipt (e.g. `'ᾠ'`) titlecase to the uppercase vowel
1563    /// with iota subscript (`'ᾨ'`) but uppercase to the uppercase vowel followed by
1564    /// full-size uppercase iota (`"ὨΙ"`). This is just one convention among many
1565    /// in common use, but it is the one Unicode settled on,
1566    /// so it is what this method does also.
1567    ///
1568    /// # Note on locale
1569    ///
1570    /// As stated above, this method is locale-insensitive.
1571    /// If you need locale support, consider using an external crate,
1572    /// like [`icu_casemap`](https://crates.io/crates/icu_casemap)
1573    /// which is developed by Unicode. A description of one common
1574    /// locale-dependent casing issue follows (there are others):
1575    ///
1576    /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
1577    ///
1578    /// * 'Dotless': I / ı, sometimes written ï
1579    /// * 'Dotted': İ / i
1580    ///
1581    /// Note that the lowercase dotted 'i' is the same codepoint as the Latin. Therefore:
1582    ///
1583    /// ```
1584    /// #![feature(titlecase)]
1585    /// let upper_i = 'i'.to_titlecase().to_string();
1586    /// ```
1587    ///
1588    /// `'i'`'s correct titlecase relies on the language of the text: if we're
1589    /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should
1590    /// be `"İ"`. `to_titlecase()` does not take this into account, and so:
1591    ///
1592    /// ```
1593    /// #![feature(titlecase)]
1594    /// let upper_i = 'i'.to_titlecase().to_string();
1595    ///
1596    /// assert_eq!(upper_i, "I");
1597    /// ```
1598    ///
1599    /// holds across languages.
1600    ///
1601    /// [`to_uppercase()`]: Self::to_uppercase()
1602    #[must_use = "this returns the titlecased character as a new iterator, \
1603                  without modifying the original"]
1604    #[unstable(feature = "titlecase", issue = "153892")]
1605    #[inline]
1606    pub fn to_titlecase(self) -> ToTitlecase {
1607        ToTitlecase(CaseMappingIter::new(conversions::to_title(self)))
1608    }
1609
1610    /// Returns an iterator that yields the uppercase mapping of this `char` as one or more
1611    /// `char`s.
1612    ///
1613    /// Prefer this method when converting a word into ALL CAPS, but consider [`to_titlecase()`]
1614    /// instead if you seek to capitalize Only The First Letter. See that method's documentation
1615    /// for more information on the difference between the two.
1616    ///
1617    /// If this `char` does not have an uppercase mapping, the iterator yields the same `char`.
1618    ///
1619    /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character
1620    /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
1621    ///
1622    /// [ucd]: https://www.unicode.org/reports/tr44/
1623    /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1624    ///
1625    /// If this `char` expands to multiple `char`s, the iterator yields the `char`s given by
1626    /// [`SpecialCasing.txt`]. The maximum number of `char`s in a case mapping is 3.
1627    ///
1628    /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
1629    ///
1630    /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1631    /// is independent of context and language. See [below](#note-on-locale)
1632    /// for more information.
1633    ///
1634    /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1635    /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1636    ///
1637    /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1638    ///
1639    /// # Examples
1640    ///
1641    /// `'ſt'` (U+FB05) is a single Unicode code point (a ligature) that maps to "ST" in uppercase.
1642    ///
1643    /// As an iterator:
1644    ///
1645    /// ```
1646    /// for c in 'ſt'.to_uppercase() {
1647    ///     print!("{c}");
1648    /// }
1649    /// println!();
1650    /// ```
1651    ///
1652    /// Using `println!` directly:
1653    ///
1654    /// ```
1655    /// println!("{}", 'ſt'.to_uppercase());
1656    /// ```
1657    ///
1658    /// Both are equivalent to:
1659    ///
1660    /// ```
1661    /// println!("ST");
1662    /// ```
1663    ///
1664    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1665    ///
1666    /// ```
1667    /// assert_eq!('c'.to_uppercase().to_string(), "C");
1668    /// assert_eq!('ა'.to_uppercase().to_string(), "Ა");
1669    /// assert_eq!('dž'.to_uppercase().to_string(), "DŽ");
1670    ///
1671    /// // Sometimes the result is more than one character:
1672    /// assert_eq!('ſt'.to_uppercase().to_string(), "ST");
1673    /// assert_eq!('ᾨ'.to_uppercase().to_string(), "ὨΙ");
1674    ///
1675    /// // Characters that do not have both uppercase and lowercase
1676    /// // convert into themselves.
1677    /// assert_eq!('山'.to_uppercase().to_string(), "山");
1678    /// ```
1679    ///
1680    /// # Note on locale
1681    ///
1682    /// As stated above, this method is locale-insensitive.
1683    /// If you need locale support, consider using an external crate,
1684    /// like [`icu_casemap`](https://crates.io/crates/icu_casemap)
1685    /// which is developed by Unicode. A description of one common
1686    /// locale-dependent casing issue follows (there are others):
1687    ///
1688    /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
1689    ///
1690    /// * 'Dotless': I / ı, sometimes written ï
1691    /// * 'Dotted': İ / i
1692    ///
1693    /// Note that the lowercase dotted 'i' is the same codepoint as the Latin. Therefore:
1694    ///
1695    /// ```
1696    /// let upper_i = 'i'.to_uppercase().to_string();
1697    /// ```
1698    ///
1699    /// `'i'`'s correct uppercase relies on the language of the text: if we're
1700    /// in `en-US`, it should be `"I"`, but if we're in `tr-TR` or `az-AZ`, it should
1701    /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
1702    ///
1703    /// ```
1704    /// let upper_i = 'i'.to_uppercase().to_string();
1705    ///
1706    /// assert_eq!(upper_i, "I");
1707    /// ```
1708    ///
1709    /// holds across languages.
1710    ///
1711    /// [`to_titlecase()`]: Self::to_titlecase()
1712    #[must_use = "this returns the uppercased character as a new iterator, \
1713                  without modifying the original"]
1714    #[stable(feature = "rust1", since = "1.0.0")]
1715    #[inline]
1716    pub fn to_uppercase(self) -> ToUppercase {
1717        ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
1718    }
1719
1720    /// Returns an iterator that yields the case folding of this `char` as one or more
1721    /// `char`s.
1722    ///
1723    /// Case folding is meant to be used when performing case-insensitive string comparisons.
1724    /// Case-folded strings should not usually be exposed directly to users. For most,
1725    /// but not all, characters, the casefold mapping is identical to the lowercase one.
1726    ///
1727    /// This iterator yields the `char`(s) in the common or full case folding for this `char`,
1728    /// as given by the [Unicode Character Database][ucd] [`CaseFolding.txt`].
1729    /// The maximum number of `char`s in a case folding is 3.
1730    ///
1731    /// [ucd]: https://www.unicode.org/reports/tr44/
1732    /// [`CaseFolding.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt
1733    ///
1734    ///
1735    /// No [normalization] (e.g. NFC) is performed, so visually and semantically identical characters
1736    /// might still casefold differently. For example, `'ά'` (U+03AC GREEK SMALL LETTER ALPHA WITH TONOS)
1737    /// is considered distinct from `'ά'` (U+1F71 GREEK SMALL LETTER ALPHA WITH OXIA),
1738    /// even though Unicode considers them canonically equivalent.
1739    ///
1740    /// In addition, this method is independent of language/locale,
1741    /// so the special behavior of I/ı/İ/i in Turkish and Azeri is not handled.
1742    ///
1743    /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case folding in
1744    /// general and Chapter 3 (Conformance) discusses the default algorithm for case folding.
1745    ///
1746    /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1747    ///
1748    /// # Examples
1749    ///
1750    /// The German sharp S `'ß'` (U+DF) is a single Unicode code point
1751    /// that casefolds to `"ss"`. Its uppercase variant '`ẞ`' (U+1E9E)
1752    /// has the same case-folding.
1753    ///
1754    /// As an iterator:
1755    ///
1756    /// ```
1757    /// #![feature(casefold)]
1758    /// assert!('ß'.to_casefold_unnormalized().eq(['s', 's']));
1759    /// assert!('ẞ'.to_casefold_unnormalized().eq(['s', 's']));
1760    /// ```
1761    ///
1762    /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1763    ///
1764    /// ```
1765    /// #![feature(casefold)]
1766    /// assert_eq!('ß'.to_casefold_unnormalized().to_string(), "ss");
1767    /// assert_eq!('ẞ'.to_casefold_unnormalized().to_string(), "ss");
1768    /// ```
1769    ///
1770    /// No [normalization] is performed:
1771    ///
1772    /// ```rust
1773    /// #![feature(casefold)]
1774    /// // These two characters are visually and semantically identical;
1775    /// // Unicode considers them to be canonically equivalent.
1776    /// let alpha_tonos = 'ά';
1777    /// let alpha_oxia = 'ά';
1778    ///
1779    /// // However, they are different codepoints:
1780    /// assert_eq!(alpha_tonos, '\u{03AC}');
1781    /// assert_eq!(alpha_oxia, '\u{1F71}');
1782    ///
1783    /// // Their case-foldings are likewise unequal:
1784    /// assert!(alpha_tonos.to_casefold_unnormalized().eq(['\u{03AC}']));
1785    /// assert!(alpha_oxia.to_casefold_unnormalized().eq(['\u{1F71}']));
1786    /// ```
1787    ///
1788    /// # Note on locale
1789    ///
1790    /// In Turkish and Azeri, the equivalent of 'i' in Latin has five forms instead of two:
1791    ///
1792    /// * 'Dotless': I / ı, sometimes written ï
1793    /// * 'Dotted': İ / i
1794    ///
1795    /// Note that the uppercase undotted 'I' is the same codepoint as the Latin. Therefore:
1796    ///
1797    /// ```
1798    /// #![feature(casefold)]
1799    /// let casefold_i = 'I'.to_casefold_unnormalized().to_string();
1800    /// ```
1801    ///
1802    /// `'I'`'s correct case folding relies on the language of the text: if we're
1803    /// in `en-US`, it should be `"i"`, but if we're in `tr-TR` or `az-AZ`, it should
1804    /// be `"ı"`. `to_casefold_unnormalized()` does not take this into account, and so:
1805    ///
1806    /// ```
1807    /// #![feature(casefold)]
1808    /// let casefold_i = 'I'.to_casefold_unnormalized().to_string();
1809    ///
1810    /// assert_eq!(casefold_i, "i");
1811    /// ```
1812    ///
1813    /// holds across languages.
1814    ///
1815    /// [normalization]: https://www.unicode.org/faq/normalization.html
1816    #[must_use = "this returns the case-folded character as a new iterator, \
1817                  without modifying the original"]
1818    #[unstable(feature = "casefold", issue = "157000")]
1819    #[inline]
1820    pub fn to_casefold_unnormalized(self) -> ToCasefold {
1821        ToCasefold(CaseMappingIter::new(conversions::to_casefold(self)))
1822    }
1823
1824    /// Returns the code point value as a `u32`.
1825    ///
1826    /// # Examples
1827    ///
1828    /// ```
1829    /// #![feature(char_to_u32)]
1830    ///
1831    /// let ascii = 'a';
1832    /// let heart = '❤';
1833    ///
1834    /// assert_eq!(ascii.to_u32(), 97_u32);
1835    /// assert_eq!(heart.to_u32(), 0x2764_u32);
1836    /// ```
1837    #[must_use = "this returns the result of the operation, \
1838                  without modifying the original"]
1839    #[unstable(feature = "char_to_u32", issue = "158938")]
1840    #[rustc_const_unstable(feature = "char_to_u32", issue = "158938")]
1841    #[inline(always)]
1842    pub const fn to_u32(self) -> u32 {
1843        self as u32
1844    }
1845
1846    /// Checks if the value is within the ASCII range.
1847    ///
1848    /// # Examples
1849    ///
1850    /// ```
1851    /// let ascii = 'a';
1852    /// let non_ascii = '❤';
1853    ///
1854    /// assert!(ascii.is_ascii());
1855    /// assert!(!non_ascii.is_ascii());
1856    /// ```
1857    #[must_use]
1858    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1859    #[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")]
1860    #[rustc_diagnostic_item = "char_is_ascii"]
1861    #[inline]
1862    pub const fn is_ascii(&self) -> bool {
1863        *self as u32 <= 0x7F
1864    }
1865
1866    /// Returns `Some` if the value is within the ASCII range,
1867    /// or `None` if it's not.
1868    ///
1869    /// This is preferred to [`Self::is_ascii`] when you're passing the value
1870    /// along to something else that can take [`ascii::Char`] rather than
1871    /// needing to check again for itself whether the value is in ASCII.
1872    #[must_use]
1873    #[unstable(feature = "ascii_char", issue = "110998")]
1874    #[inline]
1875    pub const fn as_ascii(&self) -> Option<ascii::Char> {
1876        if self.is_ascii() {
1877            // SAFETY: Just checked that this is ASCII.
1878            Some(unsafe { ascii::Char::from_u8_unchecked(*self as u8) })
1879        } else {
1880            None
1881        }
1882    }
1883
1884    /// Converts this char into an [ASCII character](`ascii::Char`), without
1885    /// checking whether it is valid.
1886    ///
1887    /// # Safety
1888    ///
1889    /// This char must be within the ASCII range, or else this is UB.
1890    #[must_use]
1891    #[unstable(feature = "ascii_char", issue = "110998")]
1892    #[inline]
1893    pub const unsafe fn as_ascii_unchecked(&self) -> ascii::Char {
1894        assert_unsafe_precondition!(
1895            check_library_ub,
1896            "as_ascii_unchecked requires that the char is valid ASCII",
1897            (it: &char = self) => it.is_ascii()
1898        );
1899
1900        // SAFETY: the caller promised that this char is ASCII.
1901        unsafe { ascii::Char::from_u8_unchecked(*self as u8) }
1902    }
1903
1904    /// Makes a copy of the value in its ASCII upper case equivalent.
1905    ///
1906    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1907    /// but non-ASCII letters are unchanged.
1908    ///
1909    /// To uppercase the value in-place, use [`make_ascii_uppercase()`].
1910    ///
1911    /// To uppercase ASCII characters in addition to non-ASCII characters, use
1912    /// [`to_uppercase()`].
1913    ///
1914    /// # Examples
1915    ///
1916    /// ```
1917    /// let ascii = 'a';
1918    /// let non_ascii = '❤';
1919    ///
1920    /// assert_eq!('A', ascii.to_ascii_uppercase());
1921    /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
1922    /// ```
1923    ///
1924    /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase
1925    /// [`to_uppercase()`]: #method.to_uppercase
1926    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
1927    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1928    #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1929    #[inline]
1930    pub const fn to_ascii_uppercase(&self) -> char {
1931        if self.is_ascii_lowercase() {
1932            (*self as u8).ascii_change_case_unchecked() as char
1933        } else {
1934            *self
1935        }
1936    }
1937
1938    /// Makes a copy of the value in its ASCII lower case equivalent.
1939    ///
1940    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1941    /// but non-ASCII letters are unchanged.
1942    ///
1943    /// To lowercase the value in-place, use [`make_ascii_lowercase()`].
1944    ///
1945    /// To lowercase ASCII characters in addition to non-ASCII characters, use
1946    /// [`to_lowercase()`].
1947    ///
1948    /// # Examples
1949    ///
1950    /// ```
1951    /// let ascii = 'A';
1952    /// let non_ascii = '❤';
1953    ///
1954    /// assert_eq!('a', ascii.to_ascii_lowercase());
1955    /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
1956    /// ```
1957    ///
1958    /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase
1959    /// [`to_lowercase()`]: #method.to_lowercase
1960    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
1961    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1962    #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1963    #[inline]
1964    pub const fn to_ascii_lowercase(&self) -> char {
1965        if self.is_ascii_uppercase() {
1966            (*self as u8).ascii_change_case_unchecked() as char
1967        } else {
1968            *self
1969        }
1970    }
1971
1972    /// Checks that two values are an ASCII case-insensitive match.
1973    ///
1974    /// Equivalent to <code>[to_ascii_lowercase]\(a) == [to_ascii_lowercase]\(b)</code>.
1975    ///
1976    /// # Examples
1977    ///
1978    /// ```
1979    /// let upper_a = 'A';
1980    /// let lower_a = 'a';
1981    /// let lower_z = 'z';
1982    ///
1983    /// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
1984    /// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
1985    /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
1986    /// ```
1987    ///
1988    /// [to_ascii_lowercase]: #method.to_ascii_lowercase
1989    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1990    #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1991    #[expect(clippy::manual_ignore_case_cmp, reason = "implements eq_ignore_ascii_case")]
1992    #[inline]
1993    pub const fn eq_ignore_ascii_case(&self, other: &char) -> bool {
1994        self.to_ascii_lowercase() == other.to_ascii_lowercase()
1995    }
1996
1997    /// Converts this type to its ASCII upper case equivalent in-place.
1998    ///
1999    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
2000    /// but non-ASCII letters are unchanged.
2001    ///
2002    /// To return a new uppercased value without modifying the existing one, use
2003    /// [`to_ascii_uppercase()`].
2004    ///
2005    /// # Examples
2006    ///
2007    /// ```
2008    /// let mut ascii = 'a';
2009    ///
2010    /// ascii.make_ascii_uppercase();
2011    ///
2012    /// assert_eq!('A', ascii);
2013    /// ```
2014    ///
2015    /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase
2016    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
2017    #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")]
2018    #[inline]
2019    pub const fn make_ascii_uppercase(&mut self) {
2020        *self = self.to_ascii_uppercase();
2021    }
2022
2023    /// Converts this type to its ASCII lower case equivalent in-place.
2024    ///
2025    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
2026    /// but non-ASCII letters are unchanged.
2027    ///
2028    /// To return a new lowercased value without modifying the existing one, use
2029    /// [`to_ascii_lowercase()`].
2030    ///
2031    /// # Examples
2032    ///
2033    /// ```
2034    /// let mut ascii = 'A';
2035    ///
2036    /// ascii.make_ascii_lowercase();
2037    ///
2038    /// assert_eq!('a', ascii);
2039    /// ```
2040    ///
2041    /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase
2042    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
2043    #[rustc_const_stable(feature = "const_make_ascii", since = "1.84.0")]
2044    #[inline]
2045    pub const fn make_ascii_lowercase(&mut self) {
2046        *self = self.to_ascii_lowercase();
2047    }
2048
2049    /// Checks if the value is an ASCII alphabetic character:
2050    ///
2051    /// - U+0041 'A' ..= U+005A 'Z', or
2052    /// - U+0061 'a' ..= U+007A 'z'.
2053    ///
2054    /// # Examples
2055    ///
2056    /// ```
2057    /// let uppercase_a = 'A';
2058    /// let uppercase_g = 'G';
2059    /// let a = 'a';
2060    /// let g = 'g';
2061    /// let zero = '0';
2062    /// let percent = '%';
2063    /// let space = ' ';
2064    /// let lf = '\n';
2065    /// let esc = '\x1b';
2066    ///
2067    /// assert!(uppercase_a.is_ascii_alphabetic());
2068    /// assert!(uppercase_g.is_ascii_alphabetic());
2069    /// assert!(a.is_ascii_alphabetic());
2070    /// assert!(g.is_ascii_alphabetic());
2071    /// assert!(!zero.is_ascii_alphabetic());
2072    /// assert!(!percent.is_ascii_alphabetic());
2073    /// assert!(!space.is_ascii_alphabetic());
2074    /// assert!(!lf.is_ascii_alphabetic());
2075    /// assert!(!esc.is_ascii_alphabetic());
2076    /// ```
2077    #[must_use]
2078    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2079    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2080    #[inline]
2081    pub const fn is_ascii_alphabetic(&self) -> bool {
2082        matches!(*self, 'a'..='z' | 'A'..='Z')
2083    }
2084
2085    /// Checks if the value is an ASCII uppercase character:
2086    /// U+0041 'A' ..= U+005A 'Z'.
2087    ///
2088    /// # Examples
2089    ///
2090    /// ```
2091    /// let uppercase_a = 'A';
2092    /// let uppercase_g = 'G';
2093    /// let a = 'a';
2094    /// let g = 'g';
2095    /// let zero = '0';
2096    /// let percent = '%';
2097    /// let space = ' ';
2098    /// let lf = '\n';
2099    /// let esc = '\x1b';
2100    ///
2101    /// assert!(uppercase_a.is_ascii_uppercase());
2102    /// assert!(uppercase_g.is_ascii_uppercase());
2103    /// assert!(!a.is_ascii_uppercase());
2104    /// assert!(!g.is_ascii_uppercase());
2105    /// assert!(!zero.is_ascii_uppercase());
2106    /// assert!(!percent.is_ascii_uppercase());
2107    /// assert!(!space.is_ascii_uppercase());
2108    /// assert!(!lf.is_ascii_uppercase());
2109    /// assert!(!esc.is_ascii_uppercase());
2110    /// ```
2111    #[must_use]
2112    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2113    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2114    #[inline]
2115    pub const fn is_ascii_uppercase(&self) -> bool {
2116        matches!(*self, 'A'..='Z')
2117    }
2118
2119    /// Checks if the value is an ASCII lowercase character:
2120    /// U+0061 'a' ..= U+007A 'z'.
2121    ///
2122    /// # Examples
2123    ///
2124    /// ```
2125    /// let uppercase_a = 'A';
2126    /// let uppercase_g = 'G';
2127    /// let a = 'a';
2128    /// let g = 'g';
2129    /// let zero = '0';
2130    /// let percent = '%';
2131    /// let space = ' ';
2132    /// let lf = '\n';
2133    /// let esc = '\x1b';
2134    ///
2135    /// assert!(!uppercase_a.is_ascii_lowercase());
2136    /// assert!(!uppercase_g.is_ascii_lowercase());
2137    /// assert!(a.is_ascii_lowercase());
2138    /// assert!(g.is_ascii_lowercase());
2139    /// assert!(!zero.is_ascii_lowercase());
2140    /// assert!(!percent.is_ascii_lowercase());
2141    /// assert!(!space.is_ascii_lowercase());
2142    /// assert!(!lf.is_ascii_lowercase());
2143    /// assert!(!esc.is_ascii_lowercase());
2144    /// ```
2145    #[must_use]
2146    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2147    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2148    #[inline]
2149    pub const fn is_ascii_lowercase(&self) -> bool {
2150        matches!(*self, 'a'..='z')
2151    }
2152
2153    /// Checks if the value is an ASCII alphanumeric character:
2154    ///
2155    /// - U+0041 'A' ..= U+005A 'Z', or
2156    /// - U+0061 'a' ..= U+007A 'z', or
2157    /// - U+0030 '0' ..= U+0039 '9'.
2158    ///
2159    /// # Examples
2160    ///
2161    /// ```
2162    /// let uppercase_a = 'A';
2163    /// let uppercase_g = 'G';
2164    /// let a = 'a';
2165    /// let g = 'g';
2166    /// let zero = '0';
2167    /// let percent = '%';
2168    /// let space = ' ';
2169    /// let lf = '\n';
2170    /// let esc = '\x1b';
2171    ///
2172    /// assert!(uppercase_a.is_ascii_alphanumeric());
2173    /// assert!(uppercase_g.is_ascii_alphanumeric());
2174    /// assert!(a.is_ascii_alphanumeric());
2175    /// assert!(g.is_ascii_alphanumeric());
2176    /// assert!(zero.is_ascii_alphanumeric());
2177    /// assert!(!percent.is_ascii_alphanumeric());
2178    /// assert!(!space.is_ascii_alphanumeric());
2179    /// assert!(!lf.is_ascii_alphanumeric());
2180    /// assert!(!esc.is_ascii_alphanumeric());
2181    /// ```
2182    #[must_use]
2183    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2184    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2185    #[inline]
2186    pub const fn is_ascii_alphanumeric(&self) -> bool {
2187        matches!(*self, '0'..='9') | matches!(*self, 'A'..='Z') | matches!(*self, 'a'..='z')
2188    }
2189
2190    /// Checks if the value is an ASCII decimal digit:
2191    /// U+0030 '0' ..= U+0039 '9'.
2192    ///
2193    /// # Examples
2194    ///
2195    /// ```
2196    /// let uppercase_a = 'A';
2197    /// let uppercase_g = 'G';
2198    /// let a = 'a';
2199    /// let g = 'g';
2200    /// let zero = '0';
2201    /// let percent = '%';
2202    /// let space = ' ';
2203    /// let lf = '\n';
2204    /// let esc = '\x1b';
2205    ///
2206    /// assert!(!uppercase_a.is_ascii_digit());
2207    /// assert!(!uppercase_g.is_ascii_digit());
2208    /// assert!(!a.is_ascii_digit());
2209    /// assert!(!g.is_ascii_digit());
2210    /// assert!(zero.is_ascii_digit());
2211    /// assert!(!percent.is_ascii_digit());
2212    /// assert!(!space.is_ascii_digit());
2213    /// assert!(!lf.is_ascii_digit());
2214    /// assert!(!esc.is_ascii_digit());
2215    /// ```
2216    #[must_use]
2217    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2218    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2219    #[inline]
2220    pub const fn is_ascii_digit(&self) -> bool {
2221        matches!(*self, '0'..='9')
2222    }
2223
2224    /// Checks if the value is an ASCII octal digit:
2225    /// U+0030 '0' ..= U+0037 '7'.
2226    ///
2227    /// # Examples
2228    ///
2229    /// ```
2230    /// #![feature(is_ascii_octdigit)]
2231    ///
2232    /// let uppercase_a = 'A';
2233    /// let a = 'a';
2234    /// let zero = '0';
2235    /// let seven = '7';
2236    /// let nine = '9';
2237    /// let percent = '%';
2238    /// let lf = '\n';
2239    ///
2240    /// assert!(!uppercase_a.is_ascii_octdigit());
2241    /// assert!(!a.is_ascii_octdigit());
2242    /// assert!(zero.is_ascii_octdigit());
2243    /// assert!(seven.is_ascii_octdigit());
2244    /// assert!(!nine.is_ascii_octdigit());
2245    /// assert!(!percent.is_ascii_octdigit());
2246    /// assert!(!lf.is_ascii_octdigit());
2247    /// ```
2248    #[must_use]
2249    #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
2250    #[inline]
2251    pub const fn is_ascii_octdigit(&self) -> bool {
2252        matches!(*self, '0'..='7')
2253    }
2254
2255    /// Checks if the value is an ASCII hexadecimal digit:
2256    ///
2257    /// - U+0030 '0' ..= U+0039 '9', or
2258    /// - U+0041 'A' ..= U+0046 'F', or
2259    /// - U+0061 'a' ..= U+0066 'f'.
2260    ///
2261    /// # Examples
2262    ///
2263    /// ```
2264    /// let uppercase_a = 'A';
2265    /// let uppercase_g = 'G';
2266    /// let a = 'a';
2267    /// let g = 'g';
2268    /// let zero = '0';
2269    /// let percent = '%';
2270    /// let space = ' ';
2271    /// let lf = '\n';
2272    /// let esc = '\x1b';
2273    ///
2274    /// assert!(uppercase_a.is_ascii_hexdigit());
2275    /// assert!(!uppercase_g.is_ascii_hexdigit());
2276    /// assert!(a.is_ascii_hexdigit());
2277    /// assert!(!g.is_ascii_hexdigit());
2278    /// assert!(zero.is_ascii_hexdigit());
2279    /// assert!(!percent.is_ascii_hexdigit());
2280    /// assert!(!space.is_ascii_hexdigit());
2281    /// assert!(!lf.is_ascii_hexdigit());
2282    /// assert!(!esc.is_ascii_hexdigit());
2283    /// ```
2284    #[must_use]
2285    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2286    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2287    #[inline]
2288    pub const fn is_ascii_hexdigit(&self) -> bool {
2289        matches!(*self, '0'..='9') | matches!(*self, 'A'..='F') | matches!(*self, 'a'..='f')
2290    }
2291
2292    /// Checks if the value is an ASCII punctuation or symbol character
2293    /// (i.e. not alphanumeric, whitespace, or control):
2294    ///
2295    /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
2296    /// - U+003A ..= U+0040 `: ; < = > ? @`, or
2297    /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
2298    /// - U+007B ..= U+007E `{ | } ~`
2299    ///
2300    /// # Examples
2301    ///
2302    /// ```
2303    /// let uppercase_a = 'A';
2304    /// let uppercase_g = 'G';
2305    /// let a = 'a';
2306    /// let g = 'g';
2307    /// let zero = '0';
2308    /// let percent = '%';
2309    /// let space = ' ';
2310    /// let lf = '\n';
2311    /// let esc = '\x1b';
2312    ///
2313    /// assert!(!uppercase_a.is_ascii_punctuation());
2314    /// assert!(!uppercase_g.is_ascii_punctuation());
2315    /// assert!(!a.is_ascii_punctuation());
2316    /// assert!(!g.is_ascii_punctuation());
2317    /// assert!(!zero.is_ascii_punctuation());
2318    /// assert!(percent.is_ascii_punctuation());
2319    /// assert!(!space.is_ascii_punctuation());
2320    /// assert!(!lf.is_ascii_punctuation());
2321    /// assert!(!esc.is_ascii_punctuation());
2322    /// ```
2323    #[must_use]
2324    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2325    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2326    #[inline]
2327    pub const fn is_ascii_punctuation(&self) -> bool {
2328        matches!(*self, '!'..='/')
2329            | matches!(*self, ':'..='@')
2330            | matches!(*self, '['..='`')
2331            | matches!(*self, '{'..='~')
2332    }
2333
2334    /// Checks if the value is an ASCII graphic character
2335    /// (i.e. not whitespace or control):
2336    /// U+0021 '!' ..= U+007E '~'.
2337    ///
2338    /// # Examples
2339    ///
2340    /// ```
2341    /// let uppercase_a = 'A';
2342    /// let uppercase_g = 'G';
2343    /// let a = 'a';
2344    /// let g = 'g';
2345    /// let zero = '0';
2346    /// let percent = '%';
2347    /// let space = ' ';
2348    /// let lf = '\n';
2349    /// let esc = '\x1b';
2350    ///
2351    /// assert!(uppercase_a.is_ascii_graphic());
2352    /// assert!(uppercase_g.is_ascii_graphic());
2353    /// assert!(a.is_ascii_graphic());
2354    /// assert!(g.is_ascii_graphic());
2355    /// assert!(zero.is_ascii_graphic());
2356    /// assert!(percent.is_ascii_graphic());
2357    /// assert!(!space.is_ascii_graphic());
2358    /// assert!(!lf.is_ascii_graphic());
2359    /// assert!(!esc.is_ascii_graphic());
2360    /// ```
2361    #[must_use]
2362    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2363    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2364    #[inline]
2365    pub const fn is_ascii_graphic(&self) -> bool {
2366        matches!(*self, '!'..='~')
2367    }
2368
2369    /// Checks if the value is an ASCII whitespace character:
2370    /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
2371    /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
2372    ///
2373    /// **Warning:** Because the list above excludes U+000B VERTICAL TAB,
2374    /// `c.is_ascii_whitespace()` is **not** equivalent to `c.is_ascii() && c.is_whitespace()`.
2375    ///
2376    /// Rust uses the WhatWG Infra Standard's [definition of ASCII
2377    /// whitespace][infra-aw]. There are several other definitions in
2378    /// wide use. For instance, [the POSIX locale][pct] includes
2379    /// U+000B VERTICAL TAB as well as all the above characters,
2380    /// but—from the very same specification—[the default rule for
2381    /// "field splitting" in the Bourne shell][bfs] considers *only*
2382    /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
2383    ///
2384    /// If you are writing a program that will process an existing
2385    /// file format, check what that format's definition of whitespace is
2386    /// before using this function.
2387    ///
2388    /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
2389    /// [pct]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap07.html#tag_07_03_01
2390    /// [bfs]: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_06_05
2391    ///
2392    /// # Examples
2393    ///
2394    /// ```
2395    /// let uppercase_a = 'A';
2396    /// let uppercase_g = 'G';
2397    /// let a = 'a';
2398    /// let g = 'g';
2399    /// let zero = '0';
2400    /// let percent = '%';
2401    /// let space = ' ';
2402    /// let lf = '\n';
2403    /// let esc = '\x1b';
2404    ///
2405    /// assert!(!uppercase_a.is_ascii_whitespace());
2406    /// assert!(!uppercase_g.is_ascii_whitespace());
2407    /// assert!(!a.is_ascii_whitespace());
2408    /// assert!(!g.is_ascii_whitespace());
2409    /// assert!(!zero.is_ascii_whitespace());
2410    /// assert!(!percent.is_ascii_whitespace());
2411    /// assert!(space.is_ascii_whitespace());
2412    /// assert!(lf.is_ascii_whitespace());
2413    /// assert!(!esc.is_ascii_whitespace());
2414    /// ```
2415    #[must_use]
2416    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2417    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2418    #[inline]
2419    pub const fn is_ascii_whitespace(&self) -> bool {
2420        matches!(*self, '\t' | '\n' | '\x0C' | '\r' | ' ')
2421    }
2422
2423    /// Checks if the value is an ASCII control character:
2424    /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
2425    /// Note that most ASCII whitespace characters are control
2426    /// characters, but SPACE is not.
2427    ///
2428    /// # Examples
2429    ///
2430    /// ```
2431    /// let uppercase_a = 'A';
2432    /// let uppercase_g = 'G';
2433    /// let a = 'a';
2434    /// let g = 'g';
2435    /// let zero = '0';
2436    /// let percent = '%';
2437    /// let space = ' ';
2438    /// let lf = '\n';
2439    /// let esc = '\x1b';
2440    ///
2441    /// assert!(!uppercase_a.is_ascii_control());
2442    /// assert!(!uppercase_g.is_ascii_control());
2443    /// assert!(!a.is_ascii_control());
2444    /// assert!(!g.is_ascii_control());
2445    /// assert!(!zero.is_ascii_control());
2446    /// assert!(!percent.is_ascii_control());
2447    /// assert!(!space.is_ascii_control());
2448    /// assert!(lf.is_ascii_control());
2449    /// assert!(esc.is_ascii_control());
2450    /// ```
2451    #[must_use]
2452    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
2453    #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
2454    #[inline]
2455    pub const fn is_ascii_control(&self) -> bool {
2456        matches!(*self, '\0'..='\x1F' | '\x7F')
2457    }
2458}
2459
2460pub(crate) struct EscapeDebugExtArgs {
2461    /// Escape Grapheme Extender codepoints?
2462    ///
2463    /// Note that this excludes
2464    /// U+FF9E HALFWIDTH KATAKANA VOICED SOUND MARK
2465    /// and U+FF9F HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK,
2466    /// which are never escaped, as graphically
2467    /// they are not combining. See <https://github.com/microsoft/terminal/issues/18087>
2468    /// for background on these characters.
2469    pub(crate) escape_grapheme_extender: bool,
2470
2471    /// Escape single quotes?
2472    pub(crate) escape_single_quote: bool,
2473
2474    /// Escape double quotes?
2475    pub(crate) escape_double_quote: bool,
2476}
2477
2478impl EscapeDebugExtArgs {
2479    pub(crate) const ESCAPE_ALL: Self = Self {
2480        escape_grapheme_extender: true,
2481        escape_single_quote: true,
2482        escape_double_quote: true,
2483    };
2484}
2485
2486#[inline]
2487#[must_use]
2488const fn len_utf8(code: u32) -> usize {
2489    match code {
2490        ..MAX_ONE_B => 1,
2491        ..MAX_TWO_B => 2,
2492        ..MAX_THREE_B => 3,
2493        _ => 4,
2494    }
2495}
2496
2497#[inline]
2498#[must_use]
2499const fn len_utf16(code: u32) -> usize {
2500    if (code & 0xFFFF) == code { 1 } else { 2 }
2501}
2502
2503/// Encodes a raw `u32` value as UTF-8 into the provided byte buffer,
2504/// and then returns the subslice of the buffer that contains the encoded character.
2505///
2506/// Unlike `char::encode_utf8`, this method also handles codepoints in the surrogate range.
2507/// (Creating a `char` in the surrogate range is UB.)
2508/// The result is valid [generalized UTF-8] but not valid UTF-8.
2509///
2510/// [generalized UTF-8]: https://simonsapin.github.io/wtf-8/#generalized-utf8
2511///
2512/// # Panics
2513///
2514/// Panics if the buffer is not large enough.
2515/// A buffer of length four is large enough to encode any `char`.
2516#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
2517#[doc(hidden)]
2518#[inline]
2519pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
2520    let len = len_utf8(code);
2521    if dst.len() < len {
2522        const_panic!(
2523            "encode_utf8: buffer does not have enough bytes to encode code point",
2524            "encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
2525            code: u32 = code,
2526            len: usize = len,
2527            dst_len: usize = dst.len(),
2528        );
2529    }
2530
2531    // SAFETY: `dst` is checked to be at least the length needed to encode the codepoint.
2532    unsafe { encode_utf8_raw_unchecked(code, dst.as_mut_ptr()) };
2533
2534    // SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
2535    unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
2536}
2537
2538/// Encodes a raw `u32` value as UTF-8 into the byte buffer pointed to by `dst`.
2539///
2540/// Unlike `char::encode_utf8`, this method also handles codepoints in the surrogate range.
2541/// (Creating a `char` in the surrogate range is UB.)
2542/// The result is valid [generalized UTF-8] but not valid UTF-8.
2543///
2544/// [generalized UTF-8]: https://simonsapin.github.io/wtf-8/#generalized-utf8
2545///
2546/// # Safety
2547///
2548/// The behavior is undefined if the buffer pointed to by `dst` is not
2549/// large enough to hold the encoded codepoint. A buffer of length four
2550/// is large enough to encode any `char`.
2551///
2552/// For a safe version of this function, see the [`encode_utf8_raw`] function.
2553#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
2554#[doc(hidden)]
2555#[inline]
2556pub const unsafe fn encode_utf8_raw_unchecked(code: u32, dst: *mut u8) {
2557    let len = len_utf8(code);
2558    // SAFETY: The caller must guarantee that the buffer pointed to by `dst`
2559    // is at least `len` bytes long.
2560    unsafe {
2561        if len == 1 {
2562            *dst = code as u8;
2563            return;
2564        }
2565
2566        let last1 = (code >> 0 & 0x3F) as u8 | TAG_CONT;
2567        let last2 = (code >> 6 & 0x3F) as u8 | TAG_CONT;
2568        let last3 = (code >> 12 & 0x3F) as u8 | TAG_CONT;
2569        let last4 = (code >> 18 & 0x3F) as u8 | TAG_FOUR_B;
2570
2571        if len == 2 {
2572            *dst = last2 | TAG_TWO_B;
2573            *dst.add(1) = last1;
2574            return;
2575        }
2576
2577        if len == 3 {
2578            *dst = last3 | TAG_THREE_B;
2579            *dst.add(1) = last2;
2580            *dst.add(2) = last1;
2581            return;
2582        }
2583
2584        *dst = last4;
2585        *dst.add(1) = last3;
2586        *dst.add(2) = last2;
2587        *dst.add(3) = last1;
2588    }
2589}
2590
2591/// Encodes a raw `u32` value as native endian UTF-16 into the provided `u16` buffer,
2592/// and then returns the subslice of the buffer that contains the encoded character.
2593///
2594/// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.
2595/// (Creating a `char` in the surrogate range is UB.)
2596///
2597/// # Panics
2598///
2599/// Panics if the buffer is not large enough.
2600/// A buffer of length 2 is large enough to encode any `char`.
2601#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
2602#[doc(hidden)]
2603#[inline]
2604pub const fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] {
2605    let len = len_utf16(code);
2606    match (len, &mut *dst) {
2607        (1, [a, ..]) => {
2608            *a = code as u16;
2609        }
2610        (2, [a, b, ..]) => {
2611            code -= 0x1_0000;
2612            *a = (code >> 10) as u16 | 0xD800;
2613            *b = (code & 0x3FF) as u16 | 0xDC00;
2614        }
2615        _ => {
2616            const_panic!(
2617                "encode_utf16: buffer does not have enough bytes to encode code point",
2618                "encode_utf16: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
2619                code: u32 = code,
2620                len: usize = len,
2621                dst_len: usize = dst.len(),
2622            )
2623        }
2624    };
2625    // SAFETY: `<&mut [u16]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
2626    unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
2627}