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