1#![allow(non_snake_case)]
21#![stable(feature = "rust1", since = "1.0.0")]
22
23mod convert;
24mod decode;
25mod methods;
26
27#[rustfmt::skip]
29#[stable(feature = "try_from", since = "1.34.0")]
30pub use self::convert::CharTryFromError;
31#[stable(feature = "char_from_str", since = "1.20.0")]
32pub use self::convert::ParseCharError;
33#[stable(feature = "decode_utf16", since = "1.9.0")]
34pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
35
36#[rustfmt::skip]
38#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
39pub use self::methods::encode_utf16_raw; #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
41pub use self::methods::{encode_utf8_raw, encode_utf8_raw_unchecked}; #[rustfmt::skip]
44use crate::ascii;
45pub(crate) use self::methods::EscapeDebugExtArgs;
46use crate::error::Error;
47use crate::escape::{AlwaysEscaped, EscapeIterInner, MaybeEscaped};
48use crate::fmt::{self, Write};
49use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
50use crate::num::NonZero;
51
52const TAG_CONT: u8 = 0b1000_0000;
54const TAG_TWO_B: u8 = 0b1100_0000;
55const TAG_THREE_B: u8 = 0b1110_0000;
56const TAG_FOUR_B: u8 = 0b1111_0000;
57const MAX_ONE_B: u32 = 0x80;
58const MAX_TWO_B: u32 = 0x800;
59const MAX_THREE_B: u32 = 0x10000;
60
61#[stable(feature = "rust1", since = "1.0.0")]
96#[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on `char`")]
97pub const MAX: char = char::MAX;
98
99#[stable(feature = "decode_utf16", since = "1.9.0")]
102#[deprecated(
103 since = "TBD",
104 note = "replaced by the `REPLACEMENT_CHARACTER` associated constant on `char`"
105)]
106pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
107
108#[stable(feature = "unicode_version", since = "1.45.0")]
111#[deprecated(
112 since = "TBD",
113 note = "replaced by the `UNICODE_VERSION` associated constant on `char`"
114)]
115pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
116
117#[stable(feature = "decode_utf16", since = "1.9.0")]
120#[deprecated(since = "TBD", note = "replaced by the `decode_utf16` method on `char`")]
121#[inline]
122pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
123 self::decode::decode_utf16(iter)
124}
125
126#[stable(feature = "rust1", since = "1.0.0")]
128#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
129#[deprecated(since = "TBD", note = "replaced by the `from_u32` method on `char`")]
130#[must_use]
131#[inline]
132pub const fn from_u32(i: u32) -> Option<char> {
133 self::convert::from_u32(i)
134}
135
136#[stable(feature = "char_from_unchecked", since = "1.5.0")]
139#[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
140#[deprecated(since = "TBD", note = "replaced by the `from_u32_unchecked` method on `char`")]
141#[must_use]
142#[inline]
143pub const unsafe fn from_u32_unchecked(i: u32) -> char {
144 unsafe { self::convert::from_u32_unchecked(i) }
146}
147
148#[stable(feature = "rust1", since = "1.0.0")]
150#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
151#[deprecated(since = "TBD", note = "replaced by the `from_digit` method on `char`")]
152#[must_use]
153#[inline]
154pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
155 self::convert::from_digit(num, radix)
156}
157
158#[derive(Clone, Debug)]
166#[stable(feature = "rust1", since = "1.0.0")]
167pub struct EscapeUnicode(EscapeIterInner<10, AlwaysEscaped>);
168
169impl EscapeUnicode {
170 #[inline]
171 #[ferrocene::prevalidated]
172 const fn new(c: char) -> Self {
173 Self(EscapeIterInner::unicode(c))
174 }
175}
176
177#[stable(feature = "rust1", since = "1.0.0")]
178impl Iterator for EscapeUnicode {
179 type Item = char;
180
181 #[inline]
182 fn next(&mut self) -> Option<char> {
183 self.0.next().map(char::from)
184 }
185
186 #[inline]
187 fn size_hint(&self) -> (usize, Option<usize>) {
188 let n = self.0.len();
189 (n, Some(n))
190 }
191
192 #[inline]
193 fn count(self) -> usize {
194 self.0.len()
195 }
196
197 #[inline]
198 fn last(mut self) -> Option<char> {
199 self.0.next_back().map(char::from)
200 }
201
202 #[inline]
203 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
204 self.0.advance_by(n)
205 }
206}
207
208#[stable(feature = "exact_size_escape", since = "1.11.0")]
209impl ExactSizeIterator for EscapeUnicode {
210 #[inline]
211 fn len(&self) -> usize {
212 self.0.len()
213 }
214}
215
216#[stable(feature = "fused", since = "1.26.0")]
217impl FusedIterator for EscapeUnicode {}
218
219#[stable(feature = "char_struct_display", since = "1.16.0")]
220impl fmt::Display for EscapeUnicode {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 fmt::Display::fmt(&self.0, f)
223 }
224}
225
226#[derive(Clone, Debug)]
233#[stable(feature = "rust1", since = "1.0.0")]
234pub struct EscapeDefault(EscapeIterInner<10, AlwaysEscaped>);
235
236impl EscapeDefault {
237 #[inline]
238 #[ferrocene::prevalidated]
239 const fn printable(c: ascii::Char) -> Self {
240 Self(EscapeIterInner::ascii(c.to_u8()))
241 }
242
243 #[inline]
244 #[ferrocene::prevalidated]
245 const fn backslash(c: ascii::Char) -> Self {
246 Self(EscapeIterInner::backslash(c))
247 }
248
249 #[inline]
250 #[ferrocene::prevalidated]
251 const fn unicode(c: char) -> Self {
252 Self(EscapeIterInner::unicode(c))
253 }
254}
255
256#[stable(feature = "rust1", since = "1.0.0")]
257impl Iterator for EscapeDefault {
258 type Item = char;
259
260 #[inline]
261 fn next(&mut self) -> Option<char> {
262 self.0.next().map(char::from)
263 }
264
265 #[inline]
266 fn size_hint(&self) -> (usize, Option<usize>) {
267 let n = self.0.len();
268 (n, Some(n))
269 }
270
271 #[inline]
272 fn count(self) -> usize {
273 self.0.len()
274 }
275
276 #[inline]
277 fn last(mut self) -> Option<char> {
278 self.0.next_back().map(char::from)
279 }
280
281 #[inline]
282 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
283 self.0.advance_by(n)
284 }
285}
286
287#[stable(feature = "exact_size_escape", since = "1.11.0")]
288impl ExactSizeIterator for EscapeDefault {
289 #[inline]
290 fn len(&self) -> usize {
291 self.0.len()
292 }
293}
294
295#[stable(feature = "fused", since = "1.26.0")]
296impl FusedIterator for EscapeDefault {}
297
298#[stable(feature = "char_struct_display", since = "1.16.0")]
299impl fmt::Display for EscapeDefault {
300 #[inline]
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 fmt::Display::fmt(&self.0, f)
303 }
304}
305
306#[stable(feature = "char_escape_debug", since = "1.20.0")]
313#[derive(Clone, Debug)]
314#[ferrocene::prevalidated]
315pub struct EscapeDebug(EscapeIterInner<10, MaybeEscaped>);
316
317impl EscapeDebug {
318 #[inline]
319 #[ferrocene::prevalidated]
320 const fn printable(chr: char) -> Self {
321 Self(EscapeIterInner::printable(chr))
322 }
323
324 #[inline]
325 #[ferrocene::prevalidated]
326 const fn backslash(c: ascii::Char) -> Self {
327 Self(EscapeIterInner::backslash(c))
328 }
329
330 #[inline]
331 #[ferrocene::prevalidated]
332 const fn unicode(c: char) -> Self {
333 Self(EscapeIterInner::unicode(c))
334 }
335}
336
337#[stable(feature = "char_escape_debug", since = "1.20.0")]
338impl Iterator for EscapeDebug {
339 type Item = char;
340
341 #[inline]
342 #[ferrocene::prevalidated]
343 fn next(&mut self) -> Option<char> {
344 self.0.next()
345 }
346
347 #[inline]
348 #[ferrocene::prevalidated]
349 fn size_hint(&self) -> (usize, Option<usize>) {
350 let n = self.len();
351 (n, Some(n))
352 }
353
354 #[inline]
355 #[ferrocene::prevalidated]
356 fn count(self) -> usize {
357 self.len()
358 }
359}
360
361#[stable(feature = "char_escape_debug", since = "1.20.0")]
362impl ExactSizeIterator for EscapeDebug {
363 #[ferrocene::prevalidated]
364 fn len(&self) -> usize {
365 self.0.len()
366 }
367}
368
369#[stable(feature = "fused", since = "1.26.0")]
370impl FusedIterator for EscapeDebug {}
371
372#[stable(feature = "char_escape_debug", since = "1.20.0")]
373impl fmt::Display for EscapeDebug {
374 #[inline]
375 #[ferrocene::prevalidated]
376 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377 fmt::Display::fmt(&self.0, f)
378 }
379}
380
381macro_rules! casemappingiter_impls {
382 (
383 #[$stab:meta]
384 #[$dendstab:meta]
385 #[$fusedstab:meta]
386 #[$exactstab:meta]
387 #[$displaystab:meta]
388 $(#[$attr:meta])*
389 $ITER_NAME:ident
390 ) => {
391 $(#[$attr])*
392 #[$stab]
393 #[derive(Debug, Clone)]
394 pub struct $ITER_NAME(CaseMappingIter);
395
396 #[$stab]
397 impl Iterator for $ITER_NAME {
398 type Item = char;
399 fn next(&mut self) -> Option<char> {
400 self.0.next()
401 }
402
403 fn size_hint(&self) -> (usize, Option<usize>) {
404 self.0.size_hint()
405 }
406
407 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
408 where
409 Fold: FnMut(Acc, Self::Item) -> Acc,
410 {
411 self.0.fold(init, fold)
412 }
413
414 fn count(self) -> usize {
415 self.0.count()
416 }
417
418 fn last(self) -> Option<Self::Item> {
419 self.0.last()
420 }
421
422 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
423 self.0.advance_by(n)
424 }
425
426 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
427 unsafe { self.0.__iterator_get_unchecked(idx) }
429 }
430 }
431
432 #[$dendstab]
433 impl DoubleEndedIterator for $ITER_NAME {
434 fn next_back(&mut self) -> Option<char> {
435 self.0.next_back()
436 }
437
438 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
439 where
440 Fold: FnMut(Acc, Self::Item) -> Acc,
441 {
442 self.0.rfold(init, rfold)
443 }
444
445 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
446 self.0.advance_back_by(n)
447 }
448 }
449
450 #[$fusedstab]
451 impl FusedIterator for $ITER_NAME {}
452
453 #[$exactstab]
454 impl ExactSizeIterator for $ITER_NAME {
455 fn len(&self) -> usize {
456 self.0.len()
457 }
458
459 fn is_empty(&self) -> bool {
460 self.0.is_empty()
461 }
462 }
463
464 #[unstable(feature = "trusted_len", issue = "37572")]
466 unsafe impl TrustedLen for $ITER_NAME {}
467
468 #[doc(hidden)]
470 #[unstable(feature = "std_internals", issue = "none")]
471 unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME {
472 const MAY_HAVE_SIDE_EFFECT: bool = false;
473 }
474
475 #[doc(hidden)]
477 #[unstable(feature = "std_internals", issue = "none")]
478 unsafe impl TrustedRandomAccess for $ITER_NAME {}
479
480 #[$displaystab]
481 impl fmt::Display for $ITER_NAME {
482 #[inline]
483 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484 fmt::Display::fmt(&self.0, f)
485 }
486 }
487 }
488}
489
490casemappingiter_impls! {
491 #[stable(feature = "rust1", since = "1.0.0")]
492 #[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
493 #[stable(feature = "fused", since = "1.26.0")]
494 #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
495 #[stable(feature = "char_struct_display", since = "1.16.0")]
496 ToUppercase
503}
504
505casemappingiter_impls! {
506 #[unstable(feature = "titlecase", issue = "153892")]
507 #[unstable(feature = "titlecase", issue = "153892")]
508 #[unstable(feature = "titlecase", issue = "153892")]
509 #[unstable(feature = "titlecase", issue = "153892")]
510 #[unstable(feature = "titlecase", issue = "153892")]
511 ToTitlecase
518}
519
520casemappingiter_impls! {
521 #[stable(feature = "rust1", since = "1.0.0")]
522 #[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
523 #[stable(feature = "fused", since = "1.26.0")]
524 #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
525 #[stable(feature = "char_struct_display", since = "1.16.0")]
526 ToLowercase
533}
534
535#[derive(Debug, Clone)]
536struct CaseMappingIter(core::array::IntoIter<char, 3>);
537
538impl CaseMappingIter {
539 #[inline]
540 fn new(chars: [char; 3]) -> CaseMappingIter {
541 let mut iter = chars.into_iter();
542 if chars[2] == '\0' {
543 iter.next_back();
544 if chars[1] == '\0' {
545 iter.next_back();
546
547 }
550 }
551 CaseMappingIter(iter)
552 }
553}
554
555impl Iterator for CaseMappingIter {
556 type Item = char;
557
558 fn next(&mut self) -> Option<char> {
559 self.0.next()
560 }
561
562 fn size_hint(&self) -> (usize, Option<usize>) {
563 self.0.size_hint()
564 }
565
566 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
567 where
568 Fold: FnMut(Acc, Self::Item) -> Acc,
569 {
570 self.0.fold(init, fold)
571 }
572
573 fn count(self) -> usize {
574 self.0.count()
575 }
576
577 fn last(self) -> Option<Self::Item> {
578 self.0.last()
579 }
580
581 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
582 self.0.advance_by(n)
583 }
584
585 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
586 unsafe { self.0.__iterator_get_unchecked(idx) }
588 }
589}
590
591impl DoubleEndedIterator for CaseMappingIter {
592 fn next_back(&mut self) -> Option<char> {
593 self.0.next_back()
594 }
595
596 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
597 where
598 Fold: FnMut(Acc, Self::Item) -> Acc,
599 {
600 self.0.rfold(init, rfold)
601 }
602
603 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
604 self.0.advance_back_by(n)
605 }
606}
607
608impl ExactSizeIterator for CaseMappingIter {
609 fn len(&self) -> usize {
610 self.0.len()
611 }
612
613 fn is_empty(&self) -> bool {
614 self.0.is_empty()
615 }
616}
617
618impl FusedIterator for CaseMappingIter {}
619
620unsafe impl TrustedLen for CaseMappingIter {}
622
623unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter {
625 const MAY_HAVE_SIDE_EFFECT: bool = false;
626}
627
628unsafe impl TrustedRandomAccess for CaseMappingIter {}
630
631impl fmt::Display for CaseMappingIter {
632 #[inline]
633 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634 for c in self.0.clone() {
635 f.write_char(c)?;
636 }
637 Ok(())
638 }
639}
640
641#[stable(feature = "u8_from_char", since = "1.59.0")]
643#[derive(Debug, Copy, Clone, PartialEq, Eq)]
644pub struct TryFromCharError(pub(crate) ());
645
646#[stable(feature = "u8_from_char", since = "1.59.0")]
647impl fmt::Display for TryFromCharError {
648 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
649 "unicode code point out of range".fmt(fmt)
650 }
651}
652
653#[stable(feature = "u8_from_char", since = "1.59.0")]
654impl Error for TryFromCharError {}
655
656#[unstable(feature = "titlecase", issue = "153892")]
666#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
667pub enum CharCase {
668 Lower = 0b00,
670 Title = 0b10,
672 Upper = 0b11,
674}