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 const fn new(c: char) -> Self {
172 Self(EscapeIterInner::unicode(c))
173 }
174}
175
176#[stable(feature = "rust1", since = "1.0.0")]
177impl Iterator for EscapeUnicode {
178 type Item = char;
179
180 #[inline]
181 fn next(&mut self) -> Option<char> {
182 self.0.next().map(char::from)
183 }
184
185 #[inline]
186 fn size_hint(&self) -> (usize, Option<usize>) {
187 let n = self.0.len();
188 (n, Some(n))
189 }
190
191 #[inline]
192 fn count(self) -> usize {
193 self.0.len()
194 }
195
196 #[inline]
197 fn last(mut self) -> Option<char> {
198 self.0.next_back().map(char::from)
199 }
200
201 #[inline]
202 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
203 self.0.advance_by(n)
204 }
205}
206
207#[stable(feature = "exact_size_escape", since = "1.11.0")]
208impl ExactSizeIterator for EscapeUnicode {
209 #[inline]
210 fn len(&self) -> usize {
211 self.0.len()
212 }
213}
214
215#[stable(feature = "fused", since = "1.26.0")]
216impl FusedIterator for EscapeUnicode {}
217
218#[stable(feature = "char_struct_display", since = "1.16.0")]
219impl fmt::Display for EscapeUnicode {
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 fmt::Display::fmt(&self.0, f)
222 }
223}
224
225#[derive(Clone, Debug)]
232#[stable(feature = "rust1", since = "1.0.0")]
233pub struct EscapeDefault(EscapeIterInner<10, AlwaysEscaped>);
234
235impl EscapeDefault {
236 #[inline]
237 const fn printable(c: ascii::Char) -> Self {
238 Self(EscapeIterInner::ascii(c.to_u8()))
239 }
240
241 #[inline]
242 const fn backslash(c: ascii::Char) -> Self {
243 Self(EscapeIterInner::backslash(c))
244 }
245
246 #[inline]
247 const fn unicode(c: char) -> Self {
248 Self(EscapeIterInner::unicode(c))
249 }
250}
251
252#[stable(feature = "rust1", since = "1.0.0")]
253impl Iterator for EscapeDefault {
254 type Item = char;
255
256 #[inline]
257 fn next(&mut self) -> Option<char> {
258 self.0.next().map(char::from)
259 }
260
261 #[inline]
262 fn size_hint(&self) -> (usize, Option<usize>) {
263 let n = self.0.len();
264 (n, Some(n))
265 }
266
267 #[inline]
268 fn count(self) -> usize {
269 self.0.len()
270 }
271
272 #[inline]
273 fn last(mut self) -> Option<char> {
274 self.0.next_back().map(char::from)
275 }
276
277 #[inline]
278 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
279 self.0.advance_by(n)
280 }
281}
282
283#[stable(feature = "exact_size_escape", since = "1.11.0")]
284impl ExactSizeIterator for EscapeDefault {
285 #[inline]
286 fn len(&self) -> usize {
287 self.0.len()
288 }
289}
290
291#[stable(feature = "fused", since = "1.26.0")]
292impl FusedIterator for EscapeDefault {}
293
294#[stable(feature = "char_struct_display", since = "1.16.0")]
295impl fmt::Display for EscapeDefault {
296 #[inline]
297 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
298 fmt::Display::fmt(&self.0, f)
299 }
300}
301
302#[stable(feature = "char_escape_debug", since = "1.20.0")]
309#[derive(Clone, Debug)]
310#[ferrocene::prevalidated]
311pub struct EscapeDebug(EscapeIterInner<10, MaybeEscaped>);
312
313impl EscapeDebug {
314 #[inline]
315 #[ferrocene::prevalidated]
316 const fn printable(chr: char) -> Self {
317 Self(EscapeIterInner::printable(chr))
318 }
319
320 #[inline]
321 #[ferrocene::prevalidated]
322 const fn backslash(c: ascii::Char) -> Self {
323 Self(EscapeIterInner::backslash(c))
324 }
325
326 #[inline]
327 #[ferrocene::prevalidated]
328 const fn unicode(c: char) -> Self {
329 Self(EscapeIterInner::unicode(c))
330 }
331}
332
333#[stable(feature = "char_escape_debug", since = "1.20.0")]
334impl Iterator for EscapeDebug {
335 type Item = char;
336
337 #[inline]
338 #[ferrocene::prevalidated]
339 fn next(&mut self) -> Option<char> {
340 self.0.next()
341 }
342
343 #[inline]
344 #[ferrocene::prevalidated]
345 fn size_hint(&self) -> (usize, Option<usize>) {
346 let n = self.len();
347 (n, Some(n))
348 }
349
350 #[inline]
351 #[ferrocene::prevalidated]
352 fn count(self) -> usize {
353 self.len()
354 }
355}
356
357#[stable(feature = "char_escape_debug", since = "1.20.0")]
358impl ExactSizeIterator for EscapeDebug {
359 #[ferrocene::prevalidated]
360 fn len(&self) -> usize {
361 self.0.len()
362 }
363}
364
365#[stable(feature = "fused", since = "1.26.0")]
366impl FusedIterator for EscapeDebug {}
367
368#[stable(feature = "char_escape_debug", since = "1.20.0")]
369impl fmt::Display for EscapeDebug {
370 #[inline]
371 #[ferrocene::prevalidated]
372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 fmt::Display::fmt(&self.0, f)
374 }
375}
376
377macro_rules! casemappingiter_impls {
378 (
379 #[$stab:meta]
380 #[$dendstab:meta]
381 #[$fusedstab:meta]
382 #[$exactstab:meta]
383 #[$displaystab:meta]
384 $(#[$attr:meta])*
385 $ITER_NAME:ident
386 ) => {
387 $(#[$attr])*
388 #[$stab]
389 #[derive(Debug, Clone)]
390 pub struct $ITER_NAME(CaseMappingIter);
391
392 #[$stab]
393 impl Iterator for $ITER_NAME {
394 type Item = char;
395 fn next(&mut self) -> Option<char> {
396 self.0.next()
397 }
398
399 fn size_hint(&self) -> (usize, Option<usize>) {
400 self.0.size_hint()
401 }
402
403 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
404 where
405 Fold: FnMut(Acc, Self::Item) -> Acc,
406 {
407 self.0.fold(init, fold)
408 }
409
410 fn count(self) -> usize {
411 self.0.count()
412 }
413
414 fn last(self) -> Option<Self::Item> {
415 self.0.last()
416 }
417
418 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
419 self.0.advance_by(n)
420 }
421
422 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
423 unsafe { self.0.__iterator_get_unchecked(idx) }
425 }
426 }
427
428 #[$dendstab]
429 impl DoubleEndedIterator for $ITER_NAME {
430 fn next_back(&mut self) -> Option<char> {
431 self.0.next_back()
432 }
433
434 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
435 where
436 Fold: FnMut(Acc, Self::Item) -> Acc,
437 {
438 self.0.rfold(init, rfold)
439 }
440
441 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
442 self.0.advance_back_by(n)
443 }
444 }
445
446 #[$fusedstab]
447 impl FusedIterator for $ITER_NAME {}
448
449 #[$exactstab]
450 impl ExactSizeIterator for $ITER_NAME {
451 fn len(&self) -> usize {
452 self.0.len()
453 }
454
455 fn is_empty(&self) -> bool {
456 self.0.is_empty()
457 }
458 }
459
460 #[unstable(feature = "trusted_len", issue = "37572")]
462 unsafe impl TrustedLen for $ITER_NAME {}
463
464 #[doc(hidden)]
466 #[unstable(feature = "std_internals", issue = "none")]
467 unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME {
468 const MAY_HAVE_SIDE_EFFECT: bool = false;
469 }
470
471 #[doc(hidden)]
473 #[unstable(feature = "std_internals", issue = "none")]
474 unsafe impl TrustedRandomAccess for $ITER_NAME {}
475
476 #[$displaystab]
477 impl fmt::Display for $ITER_NAME {
478 #[inline]
479 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
480 fmt::Display::fmt(&self.0, f)
481 }
482 }
483 }
484}
485
486casemappingiter_impls! {
487 #[stable(feature = "rust1", since = "1.0.0")]
488 #[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
489 #[stable(feature = "fused", since = "1.26.0")]
490 #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
491 #[stable(feature = "char_struct_display", since = "1.16.0")]
492 ToUppercase
499}
500
501casemappingiter_impls! {
502 #[unstable(feature = "titlecase", issue = "153892")]
503 #[unstable(feature = "titlecase", issue = "153892")]
504 #[unstable(feature = "titlecase", issue = "153892")]
505 #[unstable(feature = "titlecase", issue = "153892")]
506 #[unstable(feature = "titlecase", issue = "153892")]
507 ToTitlecase
514}
515
516casemappingiter_impls! {
517 #[stable(feature = "rust1", since = "1.0.0")]
518 #[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
519 #[stable(feature = "fused", since = "1.26.0")]
520 #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
521 #[stable(feature = "char_struct_display", since = "1.16.0")]
522 ToLowercase
529}
530
531#[derive(Debug, Clone)]
532struct CaseMappingIter(core::array::IntoIter<char, 3>);
533
534impl CaseMappingIter {
535 #[inline]
536 fn new(chars: [char; 3]) -> CaseMappingIter {
537 let mut iter = chars.into_iter();
538 if chars[2] == '\0' {
539 iter.next_back();
540 if chars[1] == '\0' {
541 iter.next_back();
542
543 }
546 }
547 CaseMappingIter(iter)
548 }
549}
550
551impl Iterator for CaseMappingIter {
552 type Item = char;
553
554 fn next(&mut self) -> Option<char> {
555 self.0.next()
556 }
557
558 fn size_hint(&self) -> (usize, Option<usize>) {
559 self.0.size_hint()
560 }
561
562 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
563 where
564 Fold: FnMut(Acc, Self::Item) -> Acc,
565 {
566 self.0.fold(init, fold)
567 }
568
569 fn count(self) -> usize {
570 self.0.count()
571 }
572
573 fn last(self) -> Option<Self::Item> {
574 self.0.last()
575 }
576
577 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
578 self.0.advance_by(n)
579 }
580
581 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
582 unsafe { self.0.__iterator_get_unchecked(idx) }
584 }
585}
586
587impl DoubleEndedIterator for CaseMappingIter {
588 fn next_back(&mut self) -> Option<char> {
589 self.0.next_back()
590 }
591
592 fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc
593 where
594 Fold: FnMut(Acc, Self::Item) -> Acc,
595 {
596 self.0.rfold(init, rfold)
597 }
598
599 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
600 self.0.advance_back_by(n)
601 }
602}
603
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
614impl FusedIterator for CaseMappingIter {}
615
616unsafe impl TrustedLen for CaseMappingIter {}
618
619unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter {
621 const MAY_HAVE_SIDE_EFFECT: bool = false;
622}
623
624unsafe impl TrustedRandomAccess for CaseMappingIter {}
626
627impl fmt::Display for CaseMappingIter {
628 #[inline]
629 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630 for c in self.0.clone() {
631 f.write_char(c)?;
632 }
633 Ok(())
634 }
635}
636
637#[stable(feature = "u8_from_char", since = "1.59.0")]
639#[derive(Debug, Copy, Clone, PartialEq, Eq)]
640pub struct TryFromCharError(pub(crate) ());
641
642#[stable(feature = "u8_from_char", since = "1.59.0")]
643impl fmt::Display for TryFromCharError {
644 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
645 "unicode code point out of range".fmt(fmt)
646 }
647}
648
649#[stable(feature = "u8_from_char", since = "1.59.0")]
650impl Error for TryFromCharError {}
651
652#[unstable(feature = "titlecase", issue = "153892")]
662#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
663pub enum CharCase {
664 Lower = 0b00,
666 Title = 0b10,
668 Upper = 0b11,
670}