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