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")]
32#[cfg(not(feature = "ferrocene_subset"))]
33pub use self::convert::ParseCharError;
34#[stable(feature = "decode_utf16", since = "1.9.0")]
35pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
36
37#[rustfmt::skip]
39#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
40#[cfg(not(feature = "ferrocene_subset"))]
41pub use self::methods::encode_utf16_raw; #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
43pub use self::methods::{encode_utf8_raw, encode_utf8_raw_unchecked}; #[rustfmt::skip]
46use crate::ascii;
47pub(crate) use self::methods::EscapeDebugExtArgs;
48#[cfg(not(feature = "ferrocene_subset"))]
49use crate::error::Error;
50#[cfg(not(feature = "ferrocene_subset"))]
51use crate::escape::{AlwaysEscaped, EscapeIterInner, MaybeEscaped};
52#[cfg(not(feature = "ferrocene_subset"))]
53use crate::fmt::{self, Write};
54#[cfg(not(feature = "ferrocene_subset"))]
55use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
56#[cfg(not(feature = "ferrocene_subset"))]
57use crate::num::NonZero;
58
59#[cfg(feature = "ferrocene_subset")]
61#[rustfmt::skip]
62use crate::{
63 escape::{EscapeIterInner, MaybeEscaped},
64 fmt,
65};
66
67const TAG_CONT: u8 = 0b1000_0000;
69const TAG_TWO_B: u8 = 0b1100_0000;
70const TAG_THREE_B: u8 = 0b1110_0000;
71const TAG_FOUR_B: u8 = 0b1111_0000;
72const MAX_ONE_B: u32 = 0x80;
73const MAX_TWO_B: u32 = 0x800;
74const MAX_THREE_B: u32 = 0x10000;
75
76#[stable(feature = "rust1", since = "1.0.0")]
111#[cfg(not(feature = "ferrocene_subset"))]
112pub const MAX: char = char::MAX;
113
114#[unstable(feature = "char_max_len", issue = "121714")]
117#[cfg(not(feature = "ferrocene_subset"))]
118pub const MAX_LEN_UTF8: usize = char::MAX_LEN_UTF8;
119
120#[unstable(feature = "char_max_len", issue = "121714")]
123#[cfg(not(feature = "ferrocene_subset"))]
124pub const MAX_LEN_UTF16: usize = char::MAX_LEN_UTF16;
125
126#[stable(feature = "decode_utf16", since = "1.9.0")]
129#[cfg(not(feature = "ferrocene_subset"))]
130pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER;
131
132#[stable(feature = "unicode_version", since = "1.45.0")]
135#[cfg(not(feature = "ferrocene_subset"))]
136pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
137
138#[stable(feature = "decode_utf16", since = "1.9.0")]
141#[inline]
142#[cfg(not(feature = "ferrocene_subset"))]
143pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
144 self::decode::decode_utf16(iter)
145}
146
147#[stable(feature = "rust1", since = "1.0.0")]
149#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
150#[must_use]
151#[inline]
152#[cfg(not(feature = "ferrocene_subset"))]
153pub const fn from_u32(i: u32) -> Option<char> {
154 self::convert::from_u32(i)
155}
156
157#[stable(feature = "char_from_unchecked", since = "1.5.0")]
160#[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")]
161#[must_use]
162#[inline]
163#[cfg(not(feature = "ferrocene_subset"))]
164pub const unsafe fn from_u32_unchecked(i: u32) -> char {
165 unsafe { self::convert::from_u32_unchecked(i) }
167}
168
169#[stable(feature = "rust1", since = "1.0.0")]
171#[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
172#[must_use]
173#[inline]
174#[cfg(not(feature = "ferrocene_subset"))]
175pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
176 self::convert::from_digit(num, radix)
177}
178
179#[derive(Clone, Debug)]
187#[stable(feature = "rust1", since = "1.0.0")]
188#[cfg(not(feature = "ferrocene_subset"))]
189pub struct EscapeUnicode(EscapeIterInner<10, AlwaysEscaped>);
190
191#[cfg(not(feature = "ferrocene_subset"))]
192impl EscapeUnicode {
193 #[inline]
194 const fn new(c: char) -> Self {
195 Self(EscapeIterInner::unicode(c))
196 }
197}
198
199#[stable(feature = "rust1", since = "1.0.0")]
200#[cfg(not(feature = "ferrocene_subset"))]
201impl Iterator for EscapeUnicode {
202 type Item = char;
203
204 #[inline]
205 fn next(&mut self) -> Option<char> {
206 self.0.next().map(char::from)
207 }
208
209 #[inline]
210 fn size_hint(&self) -> (usize, Option<usize>) {
211 let n = self.0.len();
212 (n, Some(n))
213 }
214
215 #[inline]
216 fn count(self) -> usize {
217 self.0.len()
218 }
219
220 #[inline]
221 fn last(mut self) -> Option<char> {
222 self.0.next_back().map(char::from)
223 }
224
225 #[inline]
226 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
227 self.0.advance_by(n)
228 }
229}
230
231#[stable(feature = "exact_size_escape", since = "1.11.0")]
232#[cfg(not(feature = "ferrocene_subset"))]
233impl ExactSizeIterator for EscapeUnicode {
234 #[inline]
235 fn len(&self) -> usize {
236 self.0.len()
237 }
238}
239
240#[stable(feature = "fused", since = "1.26.0")]
241#[cfg(not(feature = "ferrocene_subset"))]
242impl FusedIterator for EscapeUnicode {}
243
244#[stable(feature = "char_struct_display", since = "1.16.0")]
245#[cfg(not(feature = "ferrocene_subset"))]
246impl fmt::Display for EscapeUnicode {
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248 fmt::Display::fmt(&self.0, f)
249 }
250}
251
252#[derive(Clone, Debug)]
259#[stable(feature = "rust1", since = "1.0.0")]
260#[cfg(not(feature = "ferrocene_subset"))]
261pub struct EscapeDefault(EscapeIterInner<10, AlwaysEscaped>);
262
263#[cfg(not(feature = "ferrocene_subset"))]
264impl EscapeDefault {
265 #[inline]
266 const fn printable(c: ascii::Char) -> Self {
267 Self(EscapeIterInner::ascii(c.to_u8()))
268 }
269
270 #[inline]
271 const fn backslash(c: ascii::Char) -> Self {
272 Self(EscapeIterInner::backslash(c))
273 }
274
275 #[inline]
276 const fn unicode(c: char) -> Self {
277 Self(EscapeIterInner::unicode(c))
278 }
279}
280
281#[stable(feature = "rust1", since = "1.0.0")]
282#[cfg(not(feature = "ferrocene_subset"))]
283impl Iterator for EscapeDefault {
284 type Item = char;
285
286 #[inline]
287 fn next(&mut self) -> Option<char> {
288 self.0.next().map(char::from)
289 }
290
291 #[inline]
292 fn size_hint(&self) -> (usize, Option<usize>) {
293 let n = self.0.len();
294 (n, Some(n))
295 }
296
297 #[inline]
298 fn count(self) -> usize {
299 self.0.len()
300 }
301
302 #[inline]
303 fn last(mut self) -> Option<char> {
304 self.0.next_back().map(char::from)
305 }
306
307 #[inline]
308 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
309 self.0.advance_by(n)
310 }
311}
312
313#[stable(feature = "exact_size_escape", since = "1.11.0")]
314#[cfg(not(feature = "ferrocene_subset"))]
315impl ExactSizeIterator for EscapeDefault {
316 #[inline]
317 fn len(&self) -> usize {
318 self.0.len()
319 }
320}
321
322#[stable(feature = "fused", since = "1.26.0")]
323#[cfg(not(feature = "ferrocene_subset"))]
324impl FusedIterator for EscapeDefault {}
325
326#[stable(feature = "char_struct_display", since = "1.16.0")]
327#[cfg(not(feature = "ferrocene_subset"))]
328impl fmt::Display for EscapeDefault {
329 #[inline]
330 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331 fmt::Display::fmt(&self.0, f)
332 }
333}
334
335#[stable(feature = "char_escape_debug", since = "1.20.0")]
342#[cfg_attr(not(feature = "ferrocene_subset"), derive(Clone, Debug))]
343pub struct EscapeDebug(EscapeIterInner<10, MaybeEscaped>);
344
345impl EscapeDebug {
346 #[inline]
347 const fn printable(chr: char) -> Self {
348 Self(EscapeIterInner::printable(chr))
349 }
350
351 #[inline]
352 const fn backslash(c: ascii::Char) -> Self {
353 Self(EscapeIterInner::backslash(c))
354 }
355
356 #[inline]
357 const fn unicode(c: char) -> Self {
358 Self(EscapeIterInner::unicode(c))
359 }
360}
361
362#[stable(feature = "char_escape_debug", since = "1.20.0")]
363impl Iterator for EscapeDebug {
364 type Item = char;
365
366 #[inline]
367 fn next(&mut self) -> Option<char> {
368 self.0.next()
369 }
370
371 #[inline]
372 fn size_hint(&self) -> (usize, Option<usize>) {
373 let n = self.len();
374 (n, Some(n))
375 }
376
377 #[inline]
378 fn count(self) -> usize {
379 self.len()
380 }
381}
382
383#[stable(feature = "char_escape_debug", since = "1.20.0")]
384impl ExactSizeIterator for EscapeDebug {
385 fn len(&self) -> usize {
386 self.0.len()
387 }
388}
389
390#[stable(feature = "fused", since = "1.26.0")]
391#[cfg(not(feature = "ferrocene_subset"))]
392impl FusedIterator for EscapeDebug {}
393
394#[stable(feature = "char_escape_debug", since = "1.20.0")]
395impl fmt::Display for EscapeDebug {
396 #[inline]
397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
398 fmt::Display::fmt(&self.0, f)
399 }
400}
401
402#[cfg(not(feature = "ferrocene_subset"))]
403macro_rules! casemappingiter_impls {
404 ($(#[$attr:meta])* $ITER_NAME:ident) => {
405 $(#[$attr])*
406 #[stable(feature = "rust1", since = "1.0.0")]
407 #[derive(Debug, Clone)]
408 pub struct $ITER_NAME(CaseMappingIter);
409
410 #[stable(feature = "rust1", since = "1.0.0")]
411 impl Iterator for $ITER_NAME {
412 type Item = char;
413 fn next(&mut self) -> Option<char> {
414 self.0.next()
415 }
416
417 fn size_hint(&self) -> (usize, Option<usize>) {
418 self.0.size_hint()
419 }
420
421 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
422 where
423 Fold: FnMut(Acc, Self::Item) -> Acc,
424 {
425 self.0.fold(init, fold)
426 }
427
428 fn count(self) -> usize {
429 self.0.count()
430 }
431
432 fn last(self) -> Option<Self::Item> {
433 self.0.last()
434 }
435
436 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
437 self.0.advance_by(n)
438 }
439
440 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
441 unsafe { self.0.__iterator_get_unchecked(idx) }
443 }
444 }
445
446 #[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
447 impl DoubleEndedIterator for $ITER_NAME {
448 fn next_back(&mut self) -> Option<char> {
449 self.0.next_back()
450 }
451
452 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
453 where
454 Fold: FnMut(Acc, Self::Item) -> Acc,
455 {
456 self.0.rfold(init, rfold)
457 }
458
459 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
460 self.0.advance_back_by(n)
461 }
462 }
463
464 #[stable(feature = "fused", since = "1.26.0")]
465 impl FusedIterator for $ITER_NAME {}
466
467 #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
468 impl ExactSizeIterator for $ITER_NAME {
469 fn len(&self) -> usize {
470 self.0.len()
471 }
472
473 fn is_empty(&self) -> bool {
474 self.0.is_empty()
475 }
476 }
477
478 #[unstable(feature = "trusted_len", issue = "37572")]
480 unsafe impl TrustedLen for $ITER_NAME {}
481
482 #[doc(hidden)]
484 #[unstable(feature = "std_internals", issue = "none")]
485 unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME {
486 const MAY_HAVE_SIDE_EFFECT: bool = false;
487 }
488
489 #[doc(hidden)]
491 #[unstable(feature = "std_internals", issue = "none")]
492 unsafe impl TrustedRandomAccess for $ITER_NAME {}
493
494 #[stable(feature = "char_struct_display", since = "1.16.0")]
495 impl fmt::Display for $ITER_NAME {
496 #[inline]
497 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
498 fmt::Display::fmt(&self.0, f)
499 }
500 }
501 }
502}
503
504#[cfg(not(feature = "ferrocene_subset"))]
505casemappingiter_impls! {
506 ToLowercase
513}
514
515#[cfg(not(feature = "ferrocene_subset"))]
516casemappingiter_impls! {
517 ToUppercase
524}
525
526#[derive(Debug, Clone)]
527#[cfg(not(feature = "ferrocene_subset"))]
528struct CaseMappingIter(core::array::IntoIter<char, 3>);
529
530#[cfg(not(feature = "ferrocene_subset"))]
531impl CaseMappingIter {
532 #[inline]
533 fn new(chars: [char; 3]) -> CaseMappingIter {
534 let mut iter = chars.into_iter();
535 if chars[2] == '\0' {
536 iter.next_back();
537 if chars[1] == '\0' {
538 iter.next_back();
539
540 }
543 }
544 CaseMappingIter(iter)
545 }
546}
547
548#[cfg(not(feature = "ferrocene_subset"))]
549impl Iterator for CaseMappingIter {
550 type Item = char;
551
552 fn next(&mut self) -> Option<char> {
553 self.0.next()
554 }
555
556 fn size_hint(&self) -> (usize, Option<usize>) {
557 self.0.size_hint()
558 }
559
560 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
561 where
562 Fold: FnMut(Acc, Self::Item) -> Acc,
563 {
564 self.0.fold(init, fold)
565 }
566
567 fn count(self) -> usize {
568 self.0.count()
569 }
570
571 fn last(self) -> Option<Self::Item> {
572 self.0.last()
573 }
574
575 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
576 self.0.advance_by(n)
577 }
578
579 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
580 unsafe { self.0.__iterator_get_unchecked(idx) }
582 }
583}
584
585#[cfg(not(feature = "ferrocene_subset"))]
586impl DoubleEndedIterator for CaseMappingIter {
587 fn next_back(&mut self) -> Option<char> {
588 self.0.next_back()
589 }
590
591 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
592 where
593 Fold: FnMut(Acc, Self::Item) -> Acc,
594 {
595 self.0.rfold(init, rfold)
596 }
597
598 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
599 self.0.advance_back_by(n)
600 }
601}
602
603#[cfg(not(feature = "ferrocene_subset"))]
604impl ExactSizeIterator for CaseMappingIter {
605 fn len(&self) -> usize {
606 self.0.len()
607 }
608
609 fn is_empty(&self) -> bool {
610 self.0.is_empty()
611 }
612}
613
614#[cfg(not(feature = "ferrocene_subset"))]
615impl FusedIterator for CaseMappingIter {}
616
617#[cfg(not(feature = "ferrocene_subset"))]
619unsafe impl TrustedLen for CaseMappingIter {}
620
621#[cfg(not(feature = "ferrocene_subset"))]
623unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter {
624 const MAY_HAVE_SIDE_EFFECT: bool = false;
625}
626
627#[cfg(not(feature = "ferrocene_subset"))]
629unsafe impl TrustedRandomAccess for CaseMappingIter {}
630
631#[cfg(not(feature = "ferrocene_subset"))]
632impl fmt::Display for CaseMappingIter {
633 #[inline]
634 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
635 for c in self.0.clone() {
636 f.write_char(c)?;
637 }
638 Ok(())
639 }
640}
641
642#[stable(feature = "u8_from_char", since = "1.59.0")]
644#[derive(Debug, Copy, Clone, PartialEq, Eq)]
645#[cfg(not(feature = "ferrocene_subset"))]
646pub struct TryFromCharError(pub(crate) ());
647
648#[stable(feature = "u8_from_char", since = "1.59.0")]
649#[cfg(not(feature = "ferrocene_subset"))]
650impl fmt::Display for TryFromCharError {
651 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
652 "unicode code point out of range".fmt(fmt)
653 }
654}
655
656#[stable(feature = "u8_from_char", since = "1.59.0")]
657#[cfg(not(feature = "ferrocene_subset"))]
658impl Error for TryFromCharError {}