]> git.lizzy.rs Git - rust.git/blob - library/core/src/char/methods.rs
Fix an edge case in `chat::DecodeUtf16::size_hint`
[rust.git] / library / core / src / char / methods.rs
1 //! impl char {}
2
3 use crate::slice;
4 use crate::str::from_utf8_unchecked_mut;
5 use crate::unicode::printable::is_printable;
6 use crate::unicode::{self, conversions};
7
8 use super::*;
9
10 #[lang = "char"]
11 impl char {
12     /// The highest valid code point a `char` can have.
13     ///
14     /// A `char` is a [Unicode Scalar Value], which means that it is a [Code
15     /// Point], but only ones within a certain range. `MAX` is the highest valid
16     /// code point that's a valid [Unicode Scalar Value].
17     ///
18     /// [Unicode Scalar Value]: https://www.unicode.org/glossary/#unicode_scalar_value
19     /// [Code Point]: https://www.unicode.org/glossary/#code_point
20     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
21     pub const MAX: char = '\u{10ffff}';
22
23     /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a
24     /// decoding error.
25     ///
26     /// It can occur, for example, when giving ill-formed UTF-8 bytes to
27     /// [`String::from_utf8_lossy`](../std/string/struct.String.html#method.from_utf8_lossy).
28     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
29     pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';
30
31     /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
32     /// `char` and `str` methods are based on.
33     ///
34     /// New versions of Unicode are released regularly and subsequently all methods
35     /// in the standard library depending on Unicode are updated. Therefore the
36     /// behavior of some `char` and `str` methods and the value of this constant
37     /// changes over time. This is *not* considered to be a breaking change.
38     ///
39     /// The version numbering scheme is explained in
40     /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4).
41     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
42     pub const UNICODE_VERSION: (u8, u8, u8) = crate::unicode::UNICODE_VERSION;
43
44     /// Creates an iterator over the UTF-16 encoded code points in `iter`,
45     /// returning unpaired surrogates as `Err`s.
46     ///
47     /// # Examples
48     ///
49     /// Basic usage:
50     ///
51     /// ```
52     /// use std::char::decode_utf16;
53     ///
54     /// // 𝄞mus<invalid>ic<invalid>
55     /// let v = [
56     ///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
57     /// ];
58     ///
59     /// assert_eq!(
60     ///     decode_utf16(v)
61     ///         .map(|r| r.map_err(|e| e.unpaired_surrogate()))
62     ///         .collect::<Vec<_>>(),
63     ///     vec![
64     ///         Ok('𝄞'),
65     ///         Ok('m'), Ok('u'), Ok('s'),
66     ///         Err(0xDD1E),
67     ///         Ok('i'), Ok('c'),
68     ///         Err(0xD834)
69     ///     ]
70     /// );
71     /// ```
72     ///
73     /// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
74     ///
75     /// ```
76     /// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
77     ///
78     /// // 𝄞mus<invalid>ic<invalid>
79     /// let v = [
80     ///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
81     /// ];
82     ///
83     /// assert_eq!(
84     ///     decode_utf16(v)
85     ///        .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
86     ///        .collect::<String>(),
87     ///     "𝄞mus�ic�"
88     /// );
89     /// ```
90     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
91     #[inline]
92     pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
93         super::decode::decode_utf16(iter)
94     }
95
96     /// Converts a `u32` to a `char`.
97     ///
98     /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
99     /// [`as`](../std/keyword.as.html):
100     ///
101     /// ```
102     /// let c = '💯';
103     /// let i = c as u32;
104     ///
105     /// assert_eq!(128175, i);
106     /// ```
107     ///
108     /// However, the reverse is not true: not all valid [`u32`]s are valid
109     /// `char`s. `from_u32()` will return `None` if the input is not a valid value
110     /// for a `char`.
111     ///
112     /// For an unsafe version of this function which ignores these checks, see
113     /// [`from_u32_unchecked`].
114     ///
115     /// [`from_u32_unchecked`]: #method.from_u32_unchecked
116     ///
117     /// # Examples
118     ///
119     /// Basic usage:
120     ///
121     /// ```
122     /// use std::char;
123     ///
124     /// let c = char::from_u32(0x2764);
125     ///
126     /// assert_eq!(Some('❤'), c);
127     /// ```
128     ///
129     /// Returning `None` when the input is not a valid `char`:
130     ///
131     /// ```
132     /// use std::char;
133     ///
134     /// let c = char::from_u32(0x110000);
135     ///
136     /// assert_eq!(None, c);
137     /// ```
138     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
139     #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
140     #[must_use]
141     #[inline]
142     pub const fn from_u32(i: u32) -> Option<char> {
143         super::convert::from_u32(i)
144     }
145
146     /// Converts a `u32` to a `char`, ignoring validity.
147     ///
148     /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
149     /// `as`:
150     ///
151     /// ```
152     /// let c = '💯';
153     /// let i = c as u32;
154     ///
155     /// assert_eq!(128175, i);
156     /// ```
157     ///
158     /// However, the reverse is not true: not all valid [`u32`]s are valid
159     /// `char`s. `from_u32_unchecked()` will ignore this, and blindly cast to
160     /// `char`, possibly creating an invalid one.
161     ///
162     /// # Safety
163     ///
164     /// This function is unsafe, as it may construct invalid `char` values.
165     ///
166     /// For a safe version of this function, see the [`from_u32`] function.
167     ///
168     /// [`from_u32`]: #method.from_u32
169     ///
170     /// # Examples
171     ///
172     /// Basic usage:
173     ///
174     /// ```
175     /// use std::char;
176     ///
177     /// let c = unsafe { char::from_u32_unchecked(0x2764) };
178     ///
179     /// assert_eq!('❤', c);
180     /// ```
181     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
182     #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
183     #[must_use]
184     #[inline]
185     pub const unsafe fn from_u32_unchecked(i: u32) -> char {
186         // SAFETY: the safety contract must be upheld by the caller.
187         unsafe { super::convert::from_u32_unchecked(i) }
188     }
189
190     /// Converts a digit in the given radix to a `char`.
191     ///
192     /// A 'radix' here is sometimes also called a 'base'. A radix of two
193     /// indicates a binary number, a radix of ten, decimal, and a radix of
194     /// sixteen, hexadecimal, to give some common values. Arbitrary
195     /// radices are supported.
196     ///
197     /// `from_digit()` will return `None` if the input is not a digit in
198     /// the given radix.
199     ///
200     /// # Panics
201     ///
202     /// Panics if given a radix larger than 36.
203     ///
204     /// # Examples
205     ///
206     /// Basic usage:
207     ///
208     /// ```
209     /// use std::char;
210     ///
211     /// let c = char::from_digit(4, 10);
212     ///
213     /// assert_eq!(Some('4'), c);
214     ///
215     /// // Decimal 11 is a single digit in base 16
216     /// let c = char::from_digit(11, 16);
217     ///
218     /// assert_eq!(Some('b'), c);
219     /// ```
220     ///
221     /// Returning `None` when the input is not a digit:
222     ///
223     /// ```
224     /// use std::char;
225     ///
226     /// let c = char::from_digit(20, 10);
227     ///
228     /// assert_eq!(None, c);
229     /// ```
230     ///
231     /// Passing a large radix, causing a panic:
232     ///
233     /// ```should_panic
234     /// use std::char;
235     ///
236     /// // this panics
237     /// let _c = char::from_digit(1, 37);
238     /// ```
239     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
240     #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
241     #[must_use]
242     #[inline]
243     pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
244         super::convert::from_digit(num, radix)
245     }
246
247     /// Checks if a `char` is a digit in the given radix.
248     ///
249     /// A 'radix' here is sometimes also called a 'base'. A radix of two
250     /// indicates a binary number, a radix of ten, decimal, and a radix of
251     /// sixteen, hexadecimal, to give some common values. Arbitrary
252     /// radices are supported.
253     ///
254     /// Compared to [`is_numeric()`], this function only recognizes the characters
255     /// `0-9`, `a-z` and `A-Z`.
256     ///
257     /// 'Digit' is defined to be only the following characters:
258     ///
259     /// * `0-9`
260     /// * `a-z`
261     /// * `A-Z`
262     ///
263     /// For a more comprehensive understanding of 'digit', see [`is_numeric()`].
264     ///
265     /// [`is_numeric()`]: #method.is_numeric
266     ///
267     /// # Panics
268     ///
269     /// Panics if given a radix larger than 36.
270     ///
271     /// # Examples
272     ///
273     /// Basic usage:
274     ///
275     /// ```
276     /// assert!('1'.is_digit(10));
277     /// assert!('f'.is_digit(16));
278     /// assert!(!'f'.is_digit(10));
279     /// ```
280     ///
281     /// Passing a large radix, causing a panic:
282     ///
283     /// ```should_panic
284     /// // this panics
285     /// '1'.is_digit(37);
286     /// ```
287     #[stable(feature = "rust1", since = "1.0.0")]
288     #[inline]
289     pub fn is_digit(self, radix: u32) -> bool {
290         self.to_digit(radix).is_some()
291     }
292
293     /// Converts a `char` to a digit in the given radix.
294     ///
295     /// A 'radix' here is sometimes also called a 'base'. A radix of two
296     /// indicates a binary number, a radix of ten, decimal, and a radix of
297     /// sixteen, hexadecimal, to give some common values. Arbitrary
298     /// radices are supported.
299     ///
300     /// 'Digit' is defined to be only the following characters:
301     ///
302     /// * `0-9`
303     /// * `a-z`
304     /// * `A-Z`
305     ///
306     /// # Errors
307     ///
308     /// Returns `None` if the `char` does not refer to a digit in the given radix.
309     ///
310     /// # Panics
311     ///
312     /// Panics if given a radix larger than 36.
313     ///
314     /// # Examples
315     ///
316     /// Basic usage:
317     ///
318     /// ```
319     /// assert_eq!('1'.to_digit(10), Some(1));
320     /// assert_eq!('f'.to_digit(16), Some(15));
321     /// ```
322     ///
323     /// Passing a non-digit results in failure:
324     ///
325     /// ```
326     /// assert_eq!('f'.to_digit(10), None);
327     /// assert_eq!('z'.to_digit(16), None);
328     /// ```
329     ///
330     /// Passing a large radix, causing a panic:
331     ///
332     /// ```should_panic
333     /// // this panics
334     /// let _ = '1'.to_digit(37);
335     /// ```
336     #[stable(feature = "rust1", since = "1.0.0")]
337     #[rustc_const_unstable(feature = "const_char_convert", issue = "89259")]
338     #[must_use = "this returns the result of the operation, \
339                   without modifying the original"]
340     #[inline]
341     pub const fn to_digit(self, radix: u32) -> Option<u32> {
342         assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
343         // If not a digit, a number greater than radix will be created.
344         let mut digit = (self as u32).wrapping_sub('0' as u32);
345         if radix > 10 {
346             if digit < 10 {
347                 return Some(digit);
348             }
349             // Force the 6th bit to be set to ensure ascii is lower case.
350             digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
351         }
352         // FIXME: once then_some is const fn, use it here
353         if digit < radix { Some(digit) } else { None }
354     }
355
356     /// Returns an iterator that yields the hexadecimal Unicode escape of a
357     /// character as `char`s.
358     ///
359     /// This will escape characters with the Rust syntax of the form
360     /// `\u{NNNNNN}` where `NNNNNN` is a hexadecimal representation.
361     ///
362     /// # Examples
363     ///
364     /// As an iterator:
365     ///
366     /// ```
367     /// for c in '❤'.escape_unicode() {
368     ///     print!("{}", c);
369     /// }
370     /// println!();
371     /// ```
372     ///
373     /// Using `println!` directly:
374     ///
375     /// ```
376     /// println!("{}", '❤'.escape_unicode());
377     /// ```
378     ///
379     /// Both are equivalent to:
380     ///
381     /// ```
382     /// println!("\\u{{2764}}");
383     /// ```
384     ///
385     /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
386     ///
387     /// ```
388     /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
389     /// ```
390     #[must_use = "this returns the escaped char as an iterator, \
391                   without modifying the original"]
392     #[stable(feature = "rust1", since = "1.0.0")]
393     #[inline]
394     pub fn escape_unicode(self) -> EscapeUnicode {
395         let c = self as u32;
396
397         // or-ing 1 ensures that for c==0 the code computes that one
398         // digit should be printed and (which is the same) avoids the
399         // (31 - 32) underflow
400         let msb = 31 - (c | 1).leading_zeros();
401
402         // the index of the most significant hex digit
403         let ms_hex_digit = msb / 4;
404         EscapeUnicode {
405             c: self,
406             state: EscapeUnicodeState::Backslash,
407             hex_digit_idx: ms_hex_digit as usize,
408         }
409     }
410
411     /// An extended version of `escape_debug` that optionally permits escaping
412     /// Extended Grapheme codepoints, single quotes, and double quotes. This
413     /// allows us to format characters like nonspacing marks better when they're
414     /// at the start of a string, and allows escaping single quotes in
415     /// characters, and double quotes in strings.
416     #[inline]
417     pub(crate) fn escape_debug_ext(self, args: EscapeDebugExtArgs) -> EscapeDebug {
418         let init_state = match self {
419             '\t' => EscapeDefaultState::Backslash('t'),
420             '\r' => EscapeDefaultState::Backslash('r'),
421             '\n' => EscapeDefaultState::Backslash('n'),
422             '\\' => EscapeDefaultState::Backslash(self),
423             '"' if args.escape_double_quote => EscapeDefaultState::Backslash(self),
424             '\'' if args.escape_single_quote => EscapeDefaultState::Backslash(self),
425             _ if args.escape_grapheme_extended && self.is_grapheme_extended() => {
426                 EscapeDefaultState::Unicode(self.escape_unicode())
427             }
428             _ if is_printable(self) => EscapeDefaultState::Char(self),
429             _ => EscapeDefaultState::Unicode(self.escape_unicode()),
430         };
431         EscapeDebug(EscapeDefault { state: init_state })
432     }
433
434     /// Returns an iterator that yields the literal escape code of a character
435     /// as `char`s.
436     ///
437     /// This will escape the characters similar to the [`Debug`](core::fmt::Debug) implementations
438     /// of `str` or `char`.
439     ///
440     /// # Examples
441     ///
442     /// As an iterator:
443     ///
444     /// ```
445     /// for c in '\n'.escape_debug() {
446     ///     print!("{}", c);
447     /// }
448     /// println!();
449     /// ```
450     ///
451     /// Using `println!` directly:
452     ///
453     /// ```
454     /// println!("{}", '\n'.escape_debug());
455     /// ```
456     ///
457     /// Both are equivalent to:
458     ///
459     /// ```
460     /// println!("\\n");
461     /// ```
462     ///
463     /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
464     ///
465     /// ```
466     /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
467     /// ```
468     #[must_use = "this returns the escaped char as an iterator, \
469                   without modifying the original"]
470     #[stable(feature = "char_escape_debug", since = "1.20.0")]
471     #[inline]
472     pub fn escape_debug(self) -> EscapeDebug {
473         self.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL)
474     }
475
476     /// Returns an iterator that yields the literal escape code of a character
477     /// as `char`s.
478     ///
479     /// The default is chosen with a bias toward producing literals that are
480     /// legal in a variety of languages, including C++11 and similar C-family
481     /// languages. The exact rules are:
482     ///
483     /// * Tab is escaped as `\t`.
484     /// * Carriage return is escaped as `\r`.
485     /// * Line feed is escaped as `\n`.
486     /// * Single quote is escaped as `\'`.
487     /// * Double quote is escaped as `\"`.
488     /// * Backslash is escaped as `\\`.
489     /// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
490     ///   inclusive is not escaped.
491     /// * All other characters are given hexadecimal Unicode escapes; see
492     ///   [`escape_unicode`].
493     ///
494     /// [`escape_unicode`]: #method.escape_unicode
495     ///
496     /// # Examples
497     ///
498     /// As an iterator:
499     ///
500     /// ```
501     /// for c in '"'.escape_default() {
502     ///     print!("{}", c);
503     /// }
504     /// println!();
505     /// ```
506     ///
507     /// Using `println!` directly:
508     ///
509     /// ```
510     /// println!("{}", '"'.escape_default());
511     /// ```
512     ///
513     /// Both are equivalent to:
514     ///
515     /// ```
516     /// println!("\\\"");
517     /// ```
518     ///
519     /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
520     ///
521     /// ```
522     /// assert_eq!('"'.escape_default().to_string(), "\\\"");
523     /// ```
524     #[must_use = "this returns the escaped char as an iterator, \
525                   without modifying the original"]
526     #[stable(feature = "rust1", since = "1.0.0")]
527     #[inline]
528     pub fn escape_default(self) -> EscapeDefault {
529         let init_state = match self {
530             '\t' => EscapeDefaultState::Backslash('t'),
531             '\r' => EscapeDefaultState::Backslash('r'),
532             '\n' => EscapeDefaultState::Backslash('n'),
533             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
534             '\x20'..='\x7e' => EscapeDefaultState::Char(self),
535             _ => EscapeDefaultState::Unicode(self.escape_unicode()),
536         };
537         EscapeDefault { state: init_state }
538     }
539
540     /// Returns the number of bytes this `char` would need if encoded in UTF-8.
541     ///
542     /// That number of bytes is always between 1 and 4, inclusive.
543     ///
544     /// # Examples
545     ///
546     /// Basic usage:
547     ///
548     /// ```
549     /// let len = 'A'.len_utf8();
550     /// assert_eq!(len, 1);
551     ///
552     /// let len = 'ß'.len_utf8();
553     /// assert_eq!(len, 2);
554     ///
555     /// let len = 'ℝ'.len_utf8();
556     /// assert_eq!(len, 3);
557     ///
558     /// let len = '💣'.len_utf8();
559     /// assert_eq!(len, 4);
560     /// ```
561     ///
562     /// The `&str` type guarantees that its contents are UTF-8, and so we can compare the length it
563     /// would take if each code point was represented as a `char` vs in the `&str` itself:
564     ///
565     /// ```
566     /// // as chars
567     /// let eastern = '東';
568     /// let capital = '京';
569     ///
570     /// // both can be represented as three bytes
571     /// assert_eq!(3, eastern.len_utf8());
572     /// assert_eq!(3, capital.len_utf8());
573     ///
574     /// // as a &str, these two are encoded in UTF-8
575     /// let tokyo = "東京";
576     ///
577     /// let len = eastern.len_utf8() + capital.len_utf8();
578     ///
579     /// // we can see that they take six bytes total...
580     /// assert_eq!(6, tokyo.len());
581     ///
582     /// // ... just like the &str
583     /// assert_eq!(len, tokyo.len());
584     /// ```
585     #[stable(feature = "rust1", since = "1.0.0")]
586     #[rustc_const_stable(feature = "const_char_len_utf", since = "1.52.0")]
587     #[inline]
588     pub const fn len_utf8(self) -> usize {
589         len_utf8(self as u32)
590     }
591
592     /// Returns the number of 16-bit code units this `char` would need if
593     /// encoded in UTF-16.
594     ///
595     /// See the documentation for [`len_utf8()`] for more explanation of this
596     /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
597     ///
598     /// [`len_utf8()`]: #method.len_utf8
599     ///
600     /// # Examples
601     ///
602     /// Basic usage:
603     ///
604     /// ```
605     /// let n = 'ß'.len_utf16();
606     /// assert_eq!(n, 1);
607     ///
608     /// let len = '💣'.len_utf16();
609     /// assert_eq!(len, 2);
610     /// ```
611     #[stable(feature = "rust1", since = "1.0.0")]
612     #[rustc_const_stable(feature = "const_char_len_utf", since = "1.52.0")]
613     #[inline]
614     pub const fn len_utf16(self) -> usize {
615         let ch = self as u32;
616         if (ch & 0xFFFF) == ch { 1 } else { 2 }
617     }
618
619     /// Encodes this character as UTF-8 into the provided byte buffer,
620     /// and then returns the subslice of the buffer that contains the encoded character.
621     ///
622     /// # Panics
623     ///
624     /// Panics if the buffer is not large enough.
625     /// A buffer of length four is large enough to encode any `char`.
626     ///
627     /// # Examples
628     ///
629     /// In both of these examples, 'ß' takes two bytes to encode.
630     ///
631     /// ```
632     /// let mut b = [0; 2];
633     ///
634     /// let result = 'ß'.encode_utf8(&mut b);
635     ///
636     /// assert_eq!(result, "ß");
637     ///
638     /// assert_eq!(result.len(), 2);
639     /// ```
640     ///
641     /// A buffer that's too small:
642     ///
643     /// ```should_panic
644     /// let mut b = [0; 1];
645     ///
646     /// // this panics
647     /// 'ß'.encode_utf8(&mut b);
648     /// ```
649     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
650     #[inline]
651     pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
652         // SAFETY: `char` is not a surrogate, so this is valid UTF-8.
653         unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
654     }
655
656     /// Encodes this character as UTF-16 into the provided `u16` buffer,
657     /// and then returns the subslice of the buffer that contains the encoded character.
658     ///
659     /// # Panics
660     ///
661     /// Panics if the buffer is not large enough.
662     /// A buffer of length 2 is large enough to encode any `char`.
663     ///
664     /// # Examples
665     ///
666     /// In both of these examples, '𝕊' takes two `u16`s to encode.
667     ///
668     /// ```
669     /// let mut b = [0; 2];
670     ///
671     /// let result = '𝕊'.encode_utf16(&mut b);
672     ///
673     /// assert_eq!(result.len(), 2);
674     /// ```
675     ///
676     /// A buffer that's too small:
677     ///
678     /// ```should_panic
679     /// let mut b = [0; 1];
680     ///
681     /// // this panics
682     /// '𝕊'.encode_utf16(&mut b);
683     /// ```
684     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
685     #[inline]
686     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
687         encode_utf16_raw(self as u32, dst)
688     }
689
690     /// Returns `true` if this `char` has the `Alphabetic` property.
691     ///
692     /// `Alphabetic` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
693     /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
694     ///
695     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
696     /// [ucd]: https://www.unicode.org/reports/tr44/
697     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
698     ///
699     /// # Examples
700     ///
701     /// Basic usage:
702     ///
703     /// ```
704     /// assert!('a'.is_alphabetic());
705     /// assert!('京'.is_alphabetic());
706     ///
707     /// let c = '💝';
708     /// // love is many things, but it is not alphabetic
709     /// assert!(!c.is_alphabetic());
710     /// ```
711     #[must_use]
712     #[stable(feature = "rust1", since = "1.0.0")]
713     #[inline]
714     pub fn is_alphabetic(self) -> bool {
715         match self {
716             'a'..='z' | 'A'..='Z' => true,
717             c => c > '\x7f' && unicode::Alphabetic(c),
718         }
719     }
720
721     /// Returns `true` if this `char` has the `Lowercase` property.
722     ///
723     /// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
724     /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
725     ///
726     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
727     /// [ucd]: https://www.unicode.org/reports/tr44/
728     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
729     ///
730     /// # Examples
731     ///
732     /// Basic usage:
733     ///
734     /// ```
735     /// assert!('a'.is_lowercase());
736     /// assert!('δ'.is_lowercase());
737     /// assert!(!'A'.is_lowercase());
738     /// assert!(!'Δ'.is_lowercase());
739     ///
740     /// // The various Chinese scripts and punctuation do not have case, and so:
741     /// assert!(!'中'.is_lowercase());
742     /// assert!(!' '.is_lowercase());
743     /// ```
744     #[must_use]
745     #[stable(feature = "rust1", since = "1.0.0")]
746     #[inline]
747     pub fn is_lowercase(self) -> bool {
748         match self {
749             'a'..='z' => true,
750             c => c > '\x7f' && unicode::Lowercase(c),
751         }
752     }
753
754     /// Returns `true` if this `char` has the `Uppercase` property.
755     ///
756     /// `Uppercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
757     /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
758     ///
759     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
760     /// [ucd]: https://www.unicode.org/reports/tr44/
761     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
762     ///
763     /// # Examples
764     ///
765     /// Basic usage:
766     ///
767     /// ```
768     /// assert!(!'a'.is_uppercase());
769     /// assert!(!'δ'.is_uppercase());
770     /// assert!('A'.is_uppercase());
771     /// assert!('Δ'.is_uppercase());
772     ///
773     /// // The various Chinese scripts and punctuation do not have case, and so:
774     /// assert!(!'中'.is_uppercase());
775     /// assert!(!' '.is_uppercase());
776     /// ```
777     #[must_use]
778     #[stable(feature = "rust1", since = "1.0.0")]
779     #[inline]
780     pub fn is_uppercase(self) -> bool {
781         match self {
782             'A'..='Z' => true,
783             c => c > '\x7f' && unicode::Uppercase(c),
784         }
785     }
786
787     /// Returns `true` if this `char` has the `White_Space` property.
788     ///
789     /// `White_Space` is specified in the [Unicode Character Database][ucd] [`PropList.txt`].
790     ///
791     /// [ucd]: https://www.unicode.org/reports/tr44/
792     /// [`PropList.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
793     ///
794     /// # Examples
795     ///
796     /// Basic usage:
797     ///
798     /// ```
799     /// assert!(' '.is_whitespace());
800     ///
801     /// // a non-breaking space
802     /// assert!('\u{A0}'.is_whitespace());
803     ///
804     /// assert!(!'越'.is_whitespace());
805     /// ```
806     #[must_use]
807     #[stable(feature = "rust1", since = "1.0.0")]
808     #[inline]
809     pub fn is_whitespace(self) -> bool {
810         match self {
811             ' ' | '\x09'..='\x0d' => true,
812             c => c > '\x7f' && unicode::White_Space(c),
813         }
814     }
815
816     /// Returns `true` if this `char` satisfies either [`is_alphabetic()`] or [`is_numeric()`].
817     ///
818     /// [`is_alphabetic()`]: #method.is_alphabetic
819     /// [`is_numeric()`]: #method.is_numeric
820     ///
821     /// # Examples
822     ///
823     /// Basic usage:
824     ///
825     /// ```
826     /// assert!('٣'.is_alphanumeric());
827     /// assert!('7'.is_alphanumeric());
828     /// assert!('৬'.is_alphanumeric());
829     /// assert!('¾'.is_alphanumeric());
830     /// assert!('①'.is_alphanumeric());
831     /// assert!('K'.is_alphanumeric());
832     /// assert!('و'.is_alphanumeric());
833     /// assert!('藏'.is_alphanumeric());
834     /// ```
835     #[must_use]
836     #[stable(feature = "rust1", since = "1.0.0")]
837     #[inline]
838     pub fn is_alphanumeric(self) -> bool {
839         self.is_alphabetic() || self.is_numeric()
840     }
841
842     /// Returns `true` if this `char` has the general category for control codes.
843     ///
844     /// Control codes (code points with the general category of `Cc`) are described in Chapter 4
845     /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character
846     /// Database][ucd] [`UnicodeData.txt`].
847     ///
848     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
849     /// [ucd]: https://www.unicode.org/reports/tr44/
850     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
851     ///
852     /// # Examples
853     ///
854     /// Basic usage:
855     ///
856     /// ```
857     /// // U+009C, STRING TERMINATOR
858     /// assert!('\9c'.is_control());
859     /// assert!(!'q'.is_control());
860     /// ```
861     #[must_use]
862     #[stable(feature = "rust1", since = "1.0.0")]
863     #[inline]
864     pub fn is_control(self) -> bool {
865         unicode::Cc(self)
866     }
867
868     /// Returns `true` if this `char` has the `Grapheme_Extend` property.
869     ///
870     /// `Grapheme_Extend` is described in [Unicode Standard Annex #29 (Unicode Text
871     /// Segmentation)][uax29] and specified in the [Unicode Character Database][ucd]
872     /// [`DerivedCoreProperties.txt`].
873     ///
874     /// [uax29]: https://www.unicode.org/reports/tr29/
875     /// [ucd]: https://www.unicode.org/reports/tr44/
876     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
877     #[must_use]
878     #[inline]
879     pub(crate) fn is_grapheme_extended(self) -> bool {
880         unicode::Grapheme_Extend(self)
881     }
882
883     /// Returns `true` if this `char` has one of the general categories for numbers.
884     ///
885     /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
886     /// characters, and `No` for other numeric characters) are specified in the [Unicode Character
887     /// Database][ucd] [`UnicodeData.txt`].
888     ///
889     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
890     /// [ucd]: https://www.unicode.org/reports/tr44/
891     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
892     ///
893     /// # Examples
894     ///
895     /// Basic usage:
896     ///
897     /// ```
898     /// assert!('٣'.is_numeric());
899     /// assert!('7'.is_numeric());
900     /// assert!('৬'.is_numeric());
901     /// assert!('¾'.is_numeric());
902     /// assert!('①'.is_numeric());
903     /// assert!(!'K'.is_numeric());
904     /// assert!(!'و'.is_numeric());
905     /// assert!(!'藏'.is_numeric());
906     /// ```
907     #[must_use]
908     #[stable(feature = "rust1", since = "1.0.0")]
909     #[inline]
910     pub fn is_numeric(self) -> bool {
911         match self {
912             '0'..='9' => true,
913             c => c > '\x7f' && unicode::N(c),
914         }
915     }
916
917     /// Returns an iterator that yields the lowercase mapping of this `char` as one or more
918     /// `char`s.
919     ///
920     /// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
921     ///
922     /// If this `char` has a one-to-one lowercase mapping given by the [Unicode Character
923     /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
924     ///
925     /// [ucd]: https://www.unicode.org/reports/tr44/
926     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
927     ///
928     /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
929     /// the `char`(s) given by [`SpecialCasing.txt`].
930     ///
931     /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
932     ///
933     /// This operation performs an unconditional mapping without tailoring. That is, the conversion
934     /// is independent of context and language.
935     ///
936     /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
937     /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
938     ///
939     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
940     ///
941     /// # Examples
942     ///
943     /// As an iterator:
944     ///
945     /// ```
946     /// for c in 'İ'.to_lowercase() {
947     ///     print!("{}", c);
948     /// }
949     /// println!();
950     /// ```
951     ///
952     /// Using `println!` directly:
953     ///
954     /// ```
955     /// println!("{}", 'İ'.to_lowercase());
956     /// ```
957     ///
958     /// Both are equivalent to:
959     ///
960     /// ```
961     /// println!("i\u{307}");
962     /// ```
963     ///
964     /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
965     ///
966     /// ```
967     /// assert_eq!('C'.to_lowercase().to_string(), "c");
968     ///
969     /// // Sometimes the result is more than one character:
970     /// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
971     ///
972     /// // Characters that do not have both uppercase and lowercase
973     /// // convert into themselves.
974     /// assert_eq!('山'.to_lowercase().to_string(), "山");
975     /// ```
976     #[must_use = "this returns the lowercase character as a new iterator, \
977                   without modifying the original"]
978     #[stable(feature = "rust1", since = "1.0.0")]
979     #[inline]
980     pub fn to_lowercase(self) -> ToLowercase {
981         ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
982     }
983
984     /// Returns an iterator that yields the uppercase mapping of this `char` as one or more
985     /// `char`s.
986     ///
987     /// If this `char` does not have an uppercase mapping, the iterator yields the same `char`.
988     ///
989     /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character
990     /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
991     ///
992     /// [ucd]: https://www.unicode.org/reports/tr44/
993     /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
994     ///
995     /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
996     /// the `char`(s) given by [`SpecialCasing.txt`].
997     ///
998     /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
999     ///
1000     /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1001     /// is independent of context and language.
1002     ///
1003     /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1004     /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1005     ///
1006     /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1007     ///
1008     /// # Examples
1009     ///
1010     /// As an iterator:
1011     ///
1012     /// ```
1013     /// for c in 'ß'.to_uppercase() {
1014     ///     print!("{}", c);
1015     /// }
1016     /// println!();
1017     /// ```
1018     ///
1019     /// Using `println!` directly:
1020     ///
1021     /// ```
1022     /// println!("{}", 'ß'.to_uppercase());
1023     /// ```
1024     ///
1025     /// Both are equivalent to:
1026     ///
1027     /// ```
1028     /// println!("SS");
1029     /// ```
1030     ///
1031     /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1032     ///
1033     /// ```
1034     /// assert_eq!('c'.to_uppercase().to_string(), "C");
1035     ///
1036     /// // Sometimes the result is more than one character:
1037     /// assert_eq!('ß'.to_uppercase().to_string(), "SS");
1038     ///
1039     /// // Characters that do not have both uppercase and lowercase
1040     /// // convert into themselves.
1041     /// assert_eq!('山'.to_uppercase().to_string(), "山");
1042     /// ```
1043     ///
1044     /// # Note on locale
1045     ///
1046     /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
1047     ///
1048     /// * 'Dotless': I / ı, sometimes written ï
1049     /// * 'Dotted': İ / i
1050     ///
1051     /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
1052     ///
1053     /// ```
1054     /// let upper_i = 'i'.to_uppercase().to_string();
1055     /// ```
1056     ///
1057     /// The value of `upper_i` here relies on the language of the text: if we're
1058     /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
1059     /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
1060     ///
1061     /// ```
1062     /// let upper_i = 'i'.to_uppercase().to_string();
1063     ///
1064     /// assert_eq!(upper_i, "I");
1065     /// ```
1066     ///
1067     /// holds across languages.
1068     #[must_use = "this returns the uppercase character as a new iterator, \
1069                   without modifying the original"]
1070     #[stable(feature = "rust1", since = "1.0.0")]
1071     #[inline]
1072     pub fn to_uppercase(self) -> ToUppercase {
1073         ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
1074     }
1075
1076     /// Checks if the value is within the ASCII range.
1077     ///
1078     /// # Examples
1079     ///
1080     /// ```
1081     /// let ascii = 'a';
1082     /// let non_ascii = '❤';
1083     ///
1084     /// assert!(ascii.is_ascii());
1085     /// assert!(!non_ascii.is_ascii());
1086     /// ```
1087     #[must_use]
1088     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1089     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
1090     #[inline]
1091     pub const fn is_ascii(&self) -> bool {
1092         *self as u32 <= 0x7F
1093     }
1094
1095     /// Makes a copy of the value in its ASCII upper case equivalent.
1096     ///
1097     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1098     /// but non-ASCII letters are unchanged.
1099     ///
1100     /// To uppercase the value in-place, use [`make_ascii_uppercase()`].
1101     ///
1102     /// To uppercase ASCII characters in addition to non-ASCII characters, use
1103     /// [`to_uppercase()`].
1104     ///
1105     /// # Examples
1106     ///
1107     /// ```
1108     /// let ascii = 'a';
1109     /// let non_ascii = '❤';
1110     ///
1111     /// assert_eq!('A', ascii.to_ascii_uppercase());
1112     /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
1113     /// ```
1114     ///
1115     /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase
1116     /// [`to_uppercase()`]: #method.to_uppercase
1117     #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
1118     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1119     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1120     #[inline]
1121     pub const fn to_ascii_uppercase(&self) -> char {
1122         if self.is_ascii_lowercase() {
1123             (*self as u8).ascii_change_case_unchecked() as char
1124         } else {
1125             *self
1126         }
1127     }
1128
1129     /// Makes a copy of the value in its ASCII lower case equivalent.
1130     ///
1131     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1132     /// but non-ASCII letters are unchanged.
1133     ///
1134     /// To lowercase the value in-place, use [`make_ascii_lowercase()`].
1135     ///
1136     /// To lowercase ASCII characters in addition to non-ASCII characters, use
1137     /// [`to_lowercase()`].
1138     ///
1139     /// # Examples
1140     ///
1141     /// ```
1142     /// let ascii = 'A';
1143     /// let non_ascii = '❤';
1144     ///
1145     /// assert_eq!('a', ascii.to_ascii_lowercase());
1146     /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
1147     /// ```
1148     ///
1149     /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase
1150     /// [`to_lowercase()`]: #method.to_lowercase
1151     #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
1152     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1153     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1154     #[inline]
1155     pub const fn to_ascii_lowercase(&self) -> char {
1156         if self.is_ascii_uppercase() {
1157             (*self as u8).ascii_change_case_unchecked() as char
1158         } else {
1159             *self
1160         }
1161     }
1162
1163     /// Checks that two values are an ASCII case-insensitive match.
1164     ///
1165     /// Equivalent to <code>[to_ascii_lowercase]\(a) == [to_ascii_lowercase]\(b)</code>.
1166     ///
1167     /// # Examples
1168     ///
1169     /// ```
1170     /// let upper_a = 'A';
1171     /// let lower_a = 'a';
1172     /// let lower_z = 'z';
1173     ///
1174     /// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
1175     /// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
1176     /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
1177     /// ```
1178     ///
1179     /// [to_ascii_lowercase]: #method.to_ascii_lowercase
1180     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1181     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
1182     #[inline]
1183     pub const fn eq_ignore_ascii_case(&self, other: &char) -> bool {
1184         self.to_ascii_lowercase() == other.to_ascii_lowercase()
1185     }
1186
1187     /// Converts this type to its ASCII upper case equivalent in-place.
1188     ///
1189     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1190     /// but non-ASCII letters are unchanged.
1191     ///
1192     /// To return a new uppercased value without modifying the existing one, use
1193     /// [`to_ascii_uppercase()`].
1194     ///
1195     /// # Examples
1196     ///
1197     /// ```
1198     /// let mut ascii = 'a';
1199     ///
1200     /// ascii.make_ascii_uppercase();
1201     ///
1202     /// assert_eq!('A', ascii);
1203     /// ```
1204     ///
1205     /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase
1206     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1207     #[inline]
1208     pub fn make_ascii_uppercase(&mut self) {
1209         *self = self.to_ascii_uppercase();
1210     }
1211
1212     /// Converts this type to its ASCII lower case equivalent in-place.
1213     ///
1214     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1215     /// but non-ASCII letters are unchanged.
1216     ///
1217     /// To return a new lowercased value without modifying the existing one, use
1218     /// [`to_ascii_lowercase()`].
1219     ///
1220     /// # Examples
1221     ///
1222     /// ```
1223     /// let mut ascii = 'A';
1224     ///
1225     /// ascii.make_ascii_lowercase();
1226     ///
1227     /// assert_eq!('a', ascii);
1228     /// ```
1229     ///
1230     /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase
1231     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
1232     #[inline]
1233     pub fn make_ascii_lowercase(&mut self) {
1234         *self = self.to_ascii_lowercase();
1235     }
1236
1237     /// Checks if the value is an ASCII alphabetic character:
1238     ///
1239     /// - U+0041 'A' ..= U+005A 'Z', or
1240     /// - U+0061 'a' ..= U+007A 'z'.
1241     ///
1242     /// # Examples
1243     ///
1244     /// ```
1245     /// let uppercase_a = 'A';
1246     /// let uppercase_g = 'G';
1247     /// let a = 'a';
1248     /// let g = 'g';
1249     /// let zero = '0';
1250     /// let percent = '%';
1251     /// let space = ' ';
1252     /// let lf = '\n';
1253     /// let esc = '\x1b';
1254     ///
1255     /// assert!(uppercase_a.is_ascii_alphabetic());
1256     /// assert!(uppercase_g.is_ascii_alphabetic());
1257     /// assert!(a.is_ascii_alphabetic());
1258     /// assert!(g.is_ascii_alphabetic());
1259     /// assert!(!zero.is_ascii_alphabetic());
1260     /// assert!(!percent.is_ascii_alphabetic());
1261     /// assert!(!space.is_ascii_alphabetic());
1262     /// assert!(!lf.is_ascii_alphabetic());
1263     /// assert!(!esc.is_ascii_alphabetic());
1264     /// ```
1265     #[must_use]
1266     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1267     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1268     #[inline]
1269     pub const fn is_ascii_alphabetic(&self) -> bool {
1270         matches!(*self, 'A'..='Z' | 'a'..='z')
1271     }
1272
1273     /// Checks if the value is an ASCII uppercase character:
1274     /// U+0041 'A' ..= U+005A 'Z'.
1275     ///
1276     /// # Examples
1277     ///
1278     /// ```
1279     /// let uppercase_a = 'A';
1280     /// let uppercase_g = 'G';
1281     /// let a = 'a';
1282     /// let g = 'g';
1283     /// let zero = '0';
1284     /// let percent = '%';
1285     /// let space = ' ';
1286     /// let lf = '\n';
1287     /// let esc = '\x1b';
1288     ///
1289     /// assert!(uppercase_a.is_ascii_uppercase());
1290     /// assert!(uppercase_g.is_ascii_uppercase());
1291     /// assert!(!a.is_ascii_uppercase());
1292     /// assert!(!g.is_ascii_uppercase());
1293     /// assert!(!zero.is_ascii_uppercase());
1294     /// assert!(!percent.is_ascii_uppercase());
1295     /// assert!(!space.is_ascii_uppercase());
1296     /// assert!(!lf.is_ascii_uppercase());
1297     /// assert!(!esc.is_ascii_uppercase());
1298     /// ```
1299     #[must_use]
1300     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1301     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1302     #[inline]
1303     pub const fn is_ascii_uppercase(&self) -> bool {
1304         matches!(*self, 'A'..='Z')
1305     }
1306
1307     /// Checks if the value is an ASCII lowercase character:
1308     /// U+0061 'a' ..= U+007A 'z'.
1309     ///
1310     /// # Examples
1311     ///
1312     /// ```
1313     /// let uppercase_a = 'A';
1314     /// let uppercase_g = 'G';
1315     /// let a = 'a';
1316     /// let g = 'g';
1317     /// let zero = '0';
1318     /// let percent = '%';
1319     /// let space = ' ';
1320     /// let lf = '\n';
1321     /// let esc = '\x1b';
1322     ///
1323     /// assert!(!uppercase_a.is_ascii_lowercase());
1324     /// assert!(!uppercase_g.is_ascii_lowercase());
1325     /// assert!(a.is_ascii_lowercase());
1326     /// assert!(g.is_ascii_lowercase());
1327     /// assert!(!zero.is_ascii_lowercase());
1328     /// assert!(!percent.is_ascii_lowercase());
1329     /// assert!(!space.is_ascii_lowercase());
1330     /// assert!(!lf.is_ascii_lowercase());
1331     /// assert!(!esc.is_ascii_lowercase());
1332     /// ```
1333     #[must_use]
1334     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1335     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1336     #[inline]
1337     pub const fn is_ascii_lowercase(&self) -> bool {
1338         matches!(*self, 'a'..='z')
1339     }
1340
1341     /// Checks if the value is an ASCII alphanumeric character:
1342     ///
1343     /// - U+0041 'A' ..= U+005A 'Z', or
1344     /// - U+0061 'a' ..= U+007A 'z', or
1345     /// - U+0030 '0' ..= U+0039 '9'.
1346     ///
1347     /// # Examples
1348     ///
1349     /// ```
1350     /// let uppercase_a = 'A';
1351     /// let uppercase_g = 'G';
1352     /// let a = 'a';
1353     /// let g = 'g';
1354     /// let zero = '0';
1355     /// let percent = '%';
1356     /// let space = ' ';
1357     /// let lf = '\n';
1358     /// let esc = '\x1b';
1359     ///
1360     /// assert!(uppercase_a.is_ascii_alphanumeric());
1361     /// assert!(uppercase_g.is_ascii_alphanumeric());
1362     /// assert!(a.is_ascii_alphanumeric());
1363     /// assert!(g.is_ascii_alphanumeric());
1364     /// assert!(zero.is_ascii_alphanumeric());
1365     /// assert!(!percent.is_ascii_alphanumeric());
1366     /// assert!(!space.is_ascii_alphanumeric());
1367     /// assert!(!lf.is_ascii_alphanumeric());
1368     /// assert!(!esc.is_ascii_alphanumeric());
1369     /// ```
1370     #[must_use]
1371     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1372     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1373     #[inline]
1374     pub const fn is_ascii_alphanumeric(&self) -> bool {
1375         matches!(*self, '0'..='9' | 'A'..='Z' | 'a'..='z')
1376     }
1377
1378     /// Checks if the value is an ASCII decimal digit:
1379     /// U+0030 '0' ..= U+0039 '9'.
1380     ///
1381     /// # Examples
1382     ///
1383     /// ```
1384     /// let uppercase_a = 'A';
1385     /// let uppercase_g = 'G';
1386     /// let a = 'a';
1387     /// let g = 'g';
1388     /// let zero = '0';
1389     /// let percent = '%';
1390     /// let space = ' ';
1391     /// let lf = '\n';
1392     /// let esc = '\x1b';
1393     ///
1394     /// assert!(!uppercase_a.is_ascii_digit());
1395     /// assert!(!uppercase_g.is_ascii_digit());
1396     /// assert!(!a.is_ascii_digit());
1397     /// assert!(!g.is_ascii_digit());
1398     /// assert!(zero.is_ascii_digit());
1399     /// assert!(!percent.is_ascii_digit());
1400     /// assert!(!space.is_ascii_digit());
1401     /// assert!(!lf.is_ascii_digit());
1402     /// assert!(!esc.is_ascii_digit());
1403     /// ```
1404     #[must_use]
1405     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1406     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1407     #[inline]
1408     pub const fn is_ascii_digit(&self) -> bool {
1409         matches!(*self, '0'..='9')
1410     }
1411
1412     /// Checks if the value is an ASCII hexadecimal digit:
1413     ///
1414     /// - U+0030 '0' ..= U+0039 '9', or
1415     /// - U+0041 'A' ..= U+0046 'F', or
1416     /// - U+0061 'a' ..= U+0066 'f'.
1417     ///
1418     /// # Examples
1419     ///
1420     /// ```
1421     /// let uppercase_a = 'A';
1422     /// let uppercase_g = 'G';
1423     /// let a = 'a';
1424     /// let g = 'g';
1425     /// let zero = '0';
1426     /// let percent = '%';
1427     /// let space = ' ';
1428     /// let lf = '\n';
1429     /// let esc = '\x1b';
1430     ///
1431     /// assert!(uppercase_a.is_ascii_hexdigit());
1432     /// assert!(!uppercase_g.is_ascii_hexdigit());
1433     /// assert!(a.is_ascii_hexdigit());
1434     /// assert!(!g.is_ascii_hexdigit());
1435     /// assert!(zero.is_ascii_hexdigit());
1436     /// assert!(!percent.is_ascii_hexdigit());
1437     /// assert!(!space.is_ascii_hexdigit());
1438     /// assert!(!lf.is_ascii_hexdigit());
1439     /// assert!(!esc.is_ascii_hexdigit());
1440     /// ```
1441     #[must_use]
1442     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1443     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1444     #[inline]
1445     pub const fn is_ascii_hexdigit(&self) -> bool {
1446         matches!(*self, '0'..='9' | 'A'..='F' | 'a'..='f')
1447     }
1448
1449     /// Checks if the value is an ASCII punctuation character:
1450     ///
1451     /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
1452     /// - U+003A ..= U+0040 `: ; < = > ? @`, or
1453     /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
1454     /// - U+007B ..= U+007E `{ | } ~`
1455     ///
1456     /// # Examples
1457     ///
1458     /// ```
1459     /// let uppercase_a = 'A';
1460     /// let uppercase_g = 'G';
1461     /// let a = 'a';
1462     /// let g = 'g';
1463     /// let zero = '0';
1464     /// let percent = '%';
1465     /// let space = ' ';
1466     /// let lf = '\n';
1467     /// let esc = '\x1b';
1468     ///
1469     /// assert!(!uppercase_a.is_ascii_punctuation());
1470     /// assert!(!uppercase_g.is_ascii_punctuation());
1471     /// assert!(!a.is_ascii_punctuation());
1472     /// assert!(!g.is_ascii_punctuation());
1473     /// assert!(!zero.is_ascii_punctuation());
1474     /// assert!(percent.is_ascii_punctuation());
1475     /// assert!(!space.is_ascii_punctuation());
1476     /// assert!(!lf.is_ascii_punctuation());
1477     /// assert!(!esc.is_ascii_punctuation());
1478     /// ```
1479     #[must_use]
1480     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1481     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1482     #[inline]
1483     pub const fn is_ascii_punctuation(&self) -> bool {
1484         matches!(*self, '!'..='/' | ':'..='@' | '['..='`' | '{'..='~')
1485     }
1486
1487     /// Checks if the value is an ASCII graphic character:
1488     /// U+0021 '!' ..= U+007E '~'.
1489     ///
1490     /// # Examples
1491     ///
1492     /// ```
1493     /// let uppercase_a = 'A';
1494     /// let uppercase_g = 'G';
1495     /// let a = 'a';
1496     /// let g = 'g';
1497     /// let zero = '0';
1498     /// let percent = '%';
1499     /// let space = ' ';
1500     /// let lf = '\n';
1501     /// let esc = '\x1b';
1502     ///
1503     /// assert!(uppercase_a.is_ascii_graphic());
1504     /// assert!(uppercase_g.is_ascii_graphic());
1505     /// assert!(a.is_ascii_graphic());
1506     /// assert!(g.is_ascii_graphic());
1507     /// assert!(zero.is_ascii_graphic());
1508     /// assert!(percent.is_ascii_graphic());
1509     /// assert!(!space.is_ascii_graphic());
1510     /// assert!(!lf.is_ascii_graphic());
1511     /// assert!(!esc.is_ascii_graphic());
1512     /// ```
1513     #[must_use]
1514     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1515     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1516     #[inline]
1517     pub const fn is_ascii_graphic(&self) -> bool {
1518         matches!(*self, '!'..='~')
1519     }
1520
1521     /// Checks if the value is an ASCII whitespace character:
1522     /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
1523     /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
1524     ///
1525     /// Rust uses the WhatWG Infra Standard's [definition of ASCII
1526     /// whitespace][infra-aw]. There are several other definitions in
1527     /// wide use. For instance, [the POSIX locale][pct] includes
1528     /// U+000B VERTICAL TAB as well as all the above characters,
1529     /// but—from the very same specification—[the default rule for
1530     /// "field splitting" in the Bourne shell][bfs] considers *only*
1531     /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
1532     ///
1533     /// If you are writing a program that will process an existing
1534     /// file format, check what that format's definition of whitespace is
1535     /// before using this function.
1536     ///
1537     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
1538     /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
1539     /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
1540     ///
1541     /// # Examples
1542     ///
1543     /// ```
1544     /// let uppercase_a = 'A';
1545     /// let uppercase_g = 'G';
1546     /// let a = 'a';
1547     /// let g = 'g';
1548     /// let zero = '0';
1549     /// let percent = '%';
1550     /// let space = ' ';
1551     /// let lf = '\n';
1552     /// let esc = '\x1b';
1553     ///
1554     /// assert!(!uppercase_a.is_ascii_whitespace());
1555     /// assert!(!uppercase_g.is_ascii_whitespace());
1556     /// assert!(!a.is_ascii_whitespace());
1557     /// assert!(!g.is_ascii_whitespace());
1558     /// assert!(!zero.is_ascii_whitespace());
1559     /// assert!(!percent.is_ascii_whitespace());
1560     /// assert!(space.is_ascii_whitespace());
1561     /// assert!(lf.is_ascii_whitespace());
1562     /// assert!(!esc.is_ascii_whitespace());
1563     /// ```
1564     #[must_use]
1565     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1566     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1567     #[inline]
1568     pub const fn is_ascii_whitespace(&self) -> bool {
1569         matches!(*self, '\t' | '\n' | '\x0C' | '\r' | ' ')
1570     }
1571
1572     /// Checks if the value is an ASCII control character:
1573     /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
1574     /// Note that most ASCII whitespace characters are control
1575     /// characters, but SPACE is not.
1576     ///
1577     /// # Examples
1578     ///
1579     /// ```
1580     /// let uppercase_a = 'A';
1581     /// let uppercase_g = 'G';
1582     /// let a = 'a';
1583     /// let g = 'g';
1584     /// let zero = '0';
1585     /// let percent = '%';
1586     /// let space = ' ';
1587     /// let lf = '\n';
1588     /// let esc = '\x1b';
1589     ///
1590     /// assert!(!uppercase_a.is_ascii_control());
1591     /// assert!(!uppercase_g.is_ascii_control());
1592     /// assert!(!a.is_ascii_control());
1593     /// assert!(!g.is_ascii_control());
1594     /// assert!(!zero.is_ascii_control());
1595     /// assert!(!percent.is_ascii_control());
1596     /// assert!(!space.is_ascii_control());
1597     /// assert!(lf.is_ascii_control());
1598     /// assert!(esc.is_ascii_control());
1599     /// ```
1600     #[must_use]
1601     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
1602     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
1603     #[inline]
1604     pub const fn is_ascii_control(&self) -> bool {
1605         matches!(*self, '\0'..='\x1F' | '\x7F')
1606     }
1607 }
1608
1609 pub(crate) struct EscapeDebugExtArgs {
1610     /// Escape Extended Grapheme codepoints?
1611     pub(crate) escape_grapheme_extended: bool,
1612
1613     /// Escape single quotes?
1614     pub(crate) escape_single_quote: bool,
1615
1616     /// Escape double quotes?
1617     pub(crate) escape_double_quote: bool,
1618 }
1619
1620 impl EscapeDebugExtArgs {
1621     pub(crate) const ESCAPE_ALL: Self = Self {
1622         escape_grapheme_extended: true,
1623         escape_single_quote: true,
1624         escape_double_quote: true,
1625     };
1626 }
1627
1628 #[inline]
1629 const fn len_utf8(code: u32) -> usize {
1630     if code < MAX_ONE_B {
1631         1
1632     } else if code < MAX_TWO_B {
1633         2
1634     } else if code < MAX_THREE_B {
1635         3
1636     } else {
1637         4
1638     }
1639 }
1640
1641 /// Encodes a raw u32 value as UTF-8 into the provided byte buffer,
1642 /// and then returns the subslice of the buffer that contains the encoded character.
1643 ///
1644 /// Unlike `char::encode_utf8`, this method also handles codepoints in the surrogate range.
1645 /// (Creating a `char` in the surrogate range is UB.)
1646 /// The result is valid [generalized UTF-8] but not valid UTF-8.
1647 ///
1648 /// [generalized UTF-8]: https://simonsapin.github.io/wtf-8/#generalized-utf8
1649 ///
1650 /// # Panics
1651 ///
1652 /// Panics if the buffer is not large enough.
1653 /// A buffer of length four is large enough to encode any `char`.
1654 #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
1655 #[doc(hidden)]
1656 #[inline]
1657 pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
1658     let len = len_utf8(code);
1659     match (len, &mut dst[..]) {
1660         (1, [a, ..]) => {
1661             *a = code as u8;
1662         }
1663         (2, [a, b, ..]) => {
1664             *a = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
1665             *b = (code & 0x3F) as u8 | TAG_CONT;
1666         }
1667         (3, [a, b, c, ..]) => {
1668             *a = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
1669             *b = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1670             *c = (code & 0x3F) as u8 | TAG_CONT;
1671         }
1672         (4, [a, b, c, d, ..]) => {
1673             *a = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
1674             *b = (code >> 12 & 0x3F) as u8 | TAG_CONT;
1675             *c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
1676             *d = (code & 0x3F) as u8 | TAG_CONT;
1677         }
1678         _ => panic!(
1679             "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
1680             len,
1681             code,
1682             dst.len(),
1683         ),
1684     };
1685     &mut dst[..len]
1686 }
1687
1688 /// Encodes a raw u32 value as UTF-16 into the provided `u16` buffer,
1689 /// and then returns the subslice of the buffer that contains the encoded character.
1690 ///
1691 /// Unlike `char::encode_utf16`, this method also handles codepoints in the surrogate range.
1692 /// (Creating a `char` in the surrogate range is UB.)
1693 ///
1694 /// # Panics
1695 ///
1696 /// Panics if the buffer is not large enough.
1697 /// A buffer of length 2 is large enough to encode any `char`.
1698 #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
1699 #[doc(hidden)]
1700 #[inline]
1701 pub fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] {
1702     // SAFETY: each arm checks whether there are enough bits to write into
1703     unsafe {
1704         if (code & 0xFFFF) == code && !dst.is_empty() {
1705             // The BMP falls through
1706             *dst.get_unchecked_mut(0) = code as u16;
1707             slice::from_raw_parts_mut(dst.as_mut_ptr(), 1)
1708         } else if dst.len() >= 2 {
1709             // Supplementary planes break into surrogates.
1710             code -= 0x1_0000;
1711             *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16);
1712             *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF);
1713             slice::from_raw_parts_mut(dst.as_mut_ptr(), 2)
1714         } else {
1715             panic!(
1716                 "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}",
1717                 from_u32_unchecked(code).len_utf16(),
1718                 code,
1719                 dst.len(),
1720             )
1721         }
1722     }
1723 }