1 | //! Utilities for the `char` primitive type. |
---|---|
2 | //! |
3 | //! *[See also the `char` primitive type](primitive@char).* |
4 | //! |
5 | //! The `char` type represents a single character. More specifically, since |
6 | //! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode |
7 | //! scalar value]', which is similar to, but not the same as, a '[Unicode code |
8 | //! point]'. |
9 | //! |
10 | //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value |
11 | //! [Unicode code point]: https://www.unicode.org/glossary/#code_point |
12 | //! |
13 | //! This module exists for technical reasons, the primary documentation for |
14 | //! `char` is directly on [the `char` primitive type][char] itself. |
15 | //! |
16 | //! This module is the home of the iterator implementations for the iterators |
17 | //! implemented on `char`, as well as some useful constants and conversion |
18 | //! functions that convert various types to `char`. |
19 | |
20 | #![allow(non_snake_case)] |
21 | #![stable(feature = "rust1", since = "1.0.0")] |
22 | |
23 | mod convert; |
24 | mod decode; |
25 | mod methods; |
26 | |
27 | // stable re-exports |
28 | #[rustfmt::skip] |
29 | #[stable(feature = "try_from", since = "1.34.0")] |
30 | pub use self::convert::CharTryFromError; |
31 | #[stable(feature = "char_from_str", since = "1.20.0")] |
32 | pub use self::convert::ParseCharError; |
33 | #[stable(feature = "decode_utf16", since = "1.9.0")] |
34 | pub use self::decode::{DecodeUtf16, DecodeUtf16Error}; |
35 | |
36 | // perma-unstable re-exports |
37 | #[rustfmt::skip] |
38 | #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] |
39 | pub use self::methods::encode_utf16_raw; // perma-unstable |
40 | #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] |
41 | pub use self::methods::{encode_utf8_raw, encode_utf8_raw_unchecked}; // perma-unstable |
42 | |
43 | #[rustfmt::skip] |
44 | use crate::ascii; |
45 | pub(crate) use self::methods::EscapeDebugExtArgs; |
46 | use crate::error::Error; |
47 | use crate::escape; |
48 | use crate::fmt::{self, Write}; |
49 | use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; |
50 | use crate::num::NonZero; |
51 | |
52 | // UTF-8 ranges and tags for encoding characters |
53 | const TAG_CONT: u8 = 0b1000_0000; |
54 | const TAG_TWO_B: u8 = 0b1100_0000; |
55 | const TAG_THREE_B: u8 = 0b1110_0000; |
56 | const TAG_FOUR_B: u8 = 0b1111_0000; |
57 | const MAX_ONE_B: u32 = 0x80; |
58 | const MAX_TWO_B: u32 = 0x800; |
59 | const MAX_THREE_B: u32 = 0x10000; |
60 | |
61 | /* |
62 | Lu Uppercase_Letter an uppercase letter |
63 | Ll Lowercase_Letter a lowercase letter |
64 | Lt Titlecase_Letter a digraphic character, with first part uppercase |
65 | Lm Modifier_Letter a modifier letter |
66 | Lo Other_Letter other letters, including syllables and ideographs |
67 | Mn Nonspacing_Mark a nonspacing combining mark (zero advance width) |
68 | Mc Spacing_Mark a spacing combining mark (positive advance width) |
69 | Me Enclosing_Mark an enclosing combining mark |
70 | Nd Decimal_Number a decimal digit |
71 | Nl Letter_Number a letterlike numeric character |
72 | No Other_Number a numeric character of other type |
73 | Pc Connector_Punctuation a connecting punctuation mark, like a tie |
74 | Pd Dash_Punctuation a dash or hyphen punctuation mark |
75 | Ps Open_Punctuation an opening punctuation mark (of a pair) |
76 | Pe Close_Punctuation a closing punctuation mark (of a pair) |
77 | Pi Initial_Punctuation an initial quotation mark |
78 | Pf Final_Punctuation a final quotation mark |
79 | Po Other_Punctuation a punctuation mark of other type |
80 | Sm Math_Symbol a symbol of primarily mathematical use |
81 | Sc Currency_Symbol a currency sign |
82 | Sk Modifier_Symbol a non-letterlike modifier symbol |
83 | So Other_Symbol a symbol of other type |
84 | Zs Space_Separator a space character (of various non-zero widths) |
85 | Zl Line_Separator U+2028 LINE SEPARATOR only |
86 | Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only |
87 | Cc Control a C0 or C1 control code |
88 | Cf Format a format control character |
89 | Cs Surrogate a surrogate code point |
90 | Co Private_Use a private-use character |
91 | Cn Unassigned a reserved unassigned code point or a noncharacter |
92 | */ |
93 | |
94 | /// The highest valid code point a `char` can have, `'\u{10FFFF}'`. Use [`char::MAX`] instead. |
95 | #[stable(feature = "rust1", since = "1.0.0")] |
96 | pub const MAX: char = char::MAX; |
97 | |
98 | /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to |
99 | /// UTF-8 encoding. |
100 | #[unstable(feature = "char_max_len", issue = "121714")] |
101 | pub const MAX_LEN_UTF8: usize = char::MAX_LEN_UTF8; |
102 | |
103 | /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` |
104 | /// to UTF-16 encoding. |
105 | #[unstable(feature = "char_max_len", issue = "121714")] |
106 | pub const MAX_LEN_UTF16: usize = char::MAX_LEN_UTF16; |
107 | |
108 | /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a |
109 | /// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead. |
110 | #[stable(feature = "decode_utf16", since = "1.9.0")] |
111 | pub const REPLACEMENT_CHARACTER: char = char::REPLACEMENT_CHARACTER; |
112 | |
113 | /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of |
114 | /// `char` and `str` methods are based on. Use [`char::UNICODE_VERSION`] instead. |
115 | #[stable(feature = "unicode_version", since = "1.45.0")] |
116 | pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION; |
117 | |
118 | /// Creates an iterator over the UTF-16 encoded code points in `iter`, returning |
119 | /// unpaired surrogates as `Err`s. Use [`char::decode_utf16`] instead. |
120 | #[stable(feature = "decode_utf16", since = "1.9.0")] |
121 | #[inline] |
122 | pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> { |
123 | self::decode::decode_utf16(iter) |
124 | } |
125 | |
126 | /// Converts a `u32` to a `char`. Use [`char::from_u32`] instead. |
127 | #[stable(feature = "rust1", since = "1.0.0")] |
128 | #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")] |
129 | #[must_use] |
130 | #[inline] |
131 | pub const fn from_u32(i: u32) -> Option<char> { |
132 | self::convert::from_u32(i) |
133 | } |
134 | |
135 | /// Converts a `u32` to a `char`, ignoring validity. Use [`char::from_u32_unchecked`] |
136 | /// instead. |
137 | #[stable(feature = "char_from_unchecked", since = "1.5.0")] |
138 | #[rustc_const_stable(feature = "const_char_from_u32_unchecked", since = "1.81.0")] |
139 | #[must_use] |
140 | #[inline] |
141 | pub const unsafe fn from_u32_unchecked(i: u32) -> char { |
142 | // SAFETY: the safety contract must be upheld by the caller. |
143 | unsafe { self::convert::from_u32_unchecked(i) } |
144 | } |
145 | |
146 | /// Converts a digit in the given radix to a `char`. Use [`char::from_digit`] instead. |
147 | #[stable(feature = "rust1", since = "1.0.0")] |
148 | #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")] |
149 | #[must_use] |
150 | #[inline] |
151 | pub const fn from_digit(num: u32, radix: u32) -> Option<char> { |
152 | self::convert::from_digit(num, radix) |
153 | } |
154 | |
155 | /// Returns an iterator that yields the hexadecimal Unicode escape of a |
156 | /// character, as `char`s. |
157 | /// |
158 | /// This `struct` is created by the [`escape_unicode`] method on [`char`]. See |
159 | /// its documentation for more. |
160 | /// |
161 | /// [`escape_unicode`]: char::escape_unicode |
162 | #[derive(Clone, Debug)] |
163 | #[stable(feature = "rust1", since = "1.0.0")] |
164 | pub struct EscapeUnicode(escape::EscapeIterInner<10>); |
165 | |
166 | impl EscapeUnicode { |
167 | #[inline] |
168 | const fn new(c: char) -> Self { |
169 | Self(escape::EscapeIterInner::unicode(c)) |
170 | } |
171 | } |
172 | |
173 | #[stable(feature = "rust1", since = "1.0.0")] |
174 | impl Iterator for EscapeUnicode { |
175 | type Item = char; |
176 | |
177 | #[inline] |
178 | fn next(&mut self) -> Option<char> { |
179 | self.0.next().map(char::from) |
180 | } |
181 | |
182 | #[inline] |
183 | fn size_hint(&self) -> (usize, Option<usize>) { |
184 | let n = self.0.len(); |
185 | (n, Some(n)) |
186 | } |
187 | |
188 | #[inline] |
189 | fn count(self) -> usize { |
190 | self.0.len() |
191 | } |
192 | |
193 | #[inline] |
194 | fn last(mut self) -> Option<char> { |
195 | self.0.next_back().map(char::from) |
196 | } |
197 | |
198 | #[inline] |
199 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
200 | self.0.advance_by(n) |
201 | } |
202 | } |
203 | |
204 | #[stable(feature = "exact_size_escape", since = "1.11.0")] |
205 | impl ExactSizeIterator for EscapeUnicode { |
206 | #[inline] |
207 | fn len(&self) -> usize { |
208 | self.0.len() |
209 | } |
210 | } |
211 | |
212 | #[stable(feature = "fused", since = "1.26.0")] |
213 | impl FusedIterator for EscapeUnicode {} |
214 | |
215 | #[stable(feature = "char_struct_display", since = "1.16.0")] |
216 | impl fmt::Display for EscapeUnicode { |
217 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
218 | f.write_str(self.0.as_str()) |
219 | } |
220 | } |
221 | |
222 | /// An iterator that yields the literal escape code of a `char`. |
223 | /// |
224 | /// This `struct` is created by the [`escape_default`] method on [`char`]. See |
225 | /// its documentation for more. |
226 | /// |
227 | /// [`escape_default`]: char::escape_default |
228 | #[derive(Clone, Debug)] |
229 | #[stable(feature = "rust1", since = "1.0.0")] |
230 | pub struct EscapeDefault(escape::EscapeIterInner<10>); |
231 | |
232 | impl EscapeDefault { |
233 | #[inline] |
234 | const fn printable(c: ascii::Char) -> Self { |
235 | Self(escape::EscapeIterInner::ascii(c.to_u8())) |
236 | } |
237 | |
238 | #[inline] |
239 | const fn backslash(c: ascii::Char) -> Self { |
240 | Self(escape::EscapeIterInner::backslash(c)) |
241 | } |
242 | |
243 | #[inline] |
244 | const fn unicode(c: char) -> Self { |
245 | Self(escape::EscapeIterInner::unicode(c)) |
246 | } |
247 | } |
248 | |
249 | #[stable(feature = "rust1", since = "1.0.0")] |
250 | impl Iterator for EscapeDefault { |
251 | type Item = char; |
252 | |
253 | #[inline] |
254 | fn next(&mut self) -> Option<char> { |
255 | self.0.next().map(char::from) |
256 | } |
257 | |
258 | #[inline] |
259 | fn size_hint(&self) -> (usize, Option<usize>) { |
260 | let n = self.0.len(); |
261 | (n, Some(n)) |
262 | } |
263 | |
264 | #[inline] |
265 | fn count(self) -> usize { |
266 | self.0.len() |
267 | } |
268 | |
269 | #[inline] |
270 | fn last(mut self) -> Option<char> { |
271 | self.0.next_back().map(char::from) |
272 | } |
273 | |
274 | #[inline] |
275 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
276 | self.0.advance_by(n) |
277 | } |
278 | } |
279 | |
280 | #[stable(feature = "exact_size_escape", since = "1.11.0")] |
281 | impl ExactSizeIterator for EscapeDefault { |
282 | #[inline] |
283 | fn len(&self) -> usize { |
284 | self.0.len() |
285 | } |
286 | } |
287 | |
288 | #[stable(feature = "fused", since = "1.26.0")] |
289 | impl FusedIterator for EscapeDefault {} |
290 | |
291 | #[stable(feature = "char_struct_display", since = "1.16.0")] |
292 | impl fmt::Display for EscapeDefault { |
293 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
294 | f.write_str(self.0.as_str()) |
295 | } |
296 | } |
297 | |
298 | /// An iterator that yields the literal escape code of a `char`. |
299 | /// |
300 | /// This `struct` is created by the [`escape_debug`] method on [`char`]. See its |
301 | /// documentation for more. |
302 | /// |
303 | /// [`escape_debug`]: char::escape_debug |
304 | #[stable(feature = "char_escape_debug", since = "1.20.0")] |
305 | #[derive(Clone, Debug)] |
306 | pub struct EscapeDebug(EscapeDebugInner); |
307 | |
308 | #[derive(Clone, Debug)] |
309 | // Note: It’s possible to manually encode the EscapeDebugInner inside of |
310 | // EscapeIterInner (e.g. with alive=254..255 indicating that data[0..4] holds |
311 | // a char) which would likely result in a more optimised code. For now we use |
312 | // the option easier to implement. |
313 | enum EscapeDebugInner { |
314 | Bytes(escape::EscapeIterInner<10>), |
315 | Char(char), |
316 | } |
317 | |
318 | impl EscapeDebug { |
319 | #[inline] |
320 | const fn printable(chr: char) -> Self { |
321 | Self(EscapeDebugInner::Char(chr)) |
322 | } |
323 | |
324 | #[inline] |
325 | const fn backslash(c: ascii::Char) -> Self { |
326 | Self(EscapeDebugInner::Bytes(escape::EscapeIterInner::backslash(c))) |
327 | } |
328 | |
329 | #[inline] |
330 | const fn unicode(c: char) -> Self { |
331 | Self(EscapeDebugInner::Bytes(escape::EscapeIterInner::unicode(c))) |
332 | } |
333 | |
334 | #[inline] |
335 | fn clear(&mut self) { |
336 | self.0 = EscapeDebugInner::Bytes(escape::EscapeIterInner::empty()); |
337 | } |
338 | } |
339 | |
340 | #[stable(feature = "char_escape_debug", since = "1.20.0")] |
341 | impl Iterator for EscapeDebug { |
342 | type Item = char; |
343 | |
344 | #[inline] |
345 | fn next(&mut self) -> Option<char> { |
346 | match self.0 { |
347 | EscapeDebugInner::Bytes(ref mut bytes) => bytes.next().map(char::from), |
348 | EscapeDebugInner::Char(chr) => { |
349 | self.clear(); |
350 | Some(chr) |
351 | } |
352 | } |
353 | } |
354 | |
355 | #[inline] |
356 | fn size_hint(&self) -> (usize, Option<usize>) { |
357 | let n = self.len(); |
358 | (n, Some(n)) |
359 | } |
360 | |
361 | #[inline] |
362 | fn count(self) -> usize { |
363 | self.len() |
364 | } |
365 | } |
366 | |
367 | #[stable(feature = "char_escape_debug", since = "1.20.0")] |
368 | impl ExactSizeIterator for EscapeDebug { |
369 | fn len(&self) -> usize { |
370 | match &self.0 { |
371 | EscapeDebugInner::Bytes(bytes: &EscapeIterInner<10>) => bytes.len(), |
372 | EscapeDebugInner::Char(_) => 1, |
373 | } |
374 | } |
375 | } |
376 | |
377 | #[stable(feature = "fused", since = "1.26.0")] |
378 | impl FusedIterator for EscapeDebug {} |
379 | |
380 | #[stable(feature = "char_escape_debug", since = "1.20.0")] |
381 | impl fmt::Display for EscapeDebug { |
382 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
383 | match &self.0 { |
384 | EscapeDebugInner::Bytes(bytes: &EscapeIterInner<10>) => f.write_str(data:bytes.as_str()), |
385 | EscapeDebugInner::Char(chr: &char) => f.write_char(*chr), |
386 | } |
387 | } |
388 | } |
389 | |
390 | macro_rules! casemappingiter_impls { |
391 | ($(#[$attr:meta])* $ITER_NAME:ident) => { |
392 | $(#[$attr])* |
393 | #[stable(feature = "rust1", since = "1.0.0")] |
394 | #[derive(Debug, Clone)] |
395 | pub struct $ITER_NAME(CaseMappingIter); |
396 | |
397 | #[stable(feature = "rust1", since = "1.0.0")] |
398 | impl Iterator for $ITER_NAME { |
399 | type Item = char; |
400 | fn next(&mut self) -> Option<char> { |
401 | self.0.next() |
402 | } |
403 | |
404 | fn size_hint(&self) -> (usize, Option<usize>) { |
405 | self.0.size_hint() |
406 | } |
407 | |
408 | fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
409 | where |
410 | Fold: FnMut(Acc, Self::Item) -> Acc, |
411 | { |
412 | self.0.fold(init, fold) |
413 | } |
414 | |
415 | fn count(self) -> usize { |
416 | self.0.count() |
417 | } |
418 | |
419 | fn last(self) -> Option<Self::Item> { |
420 | self.0.last() |
421 | } |
422 | |
423 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
424 | self.0.advance_by(n) |
425 | } |
426 | |
427 | unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { |
428 | // SAFETY: just forwarding requirements to caller |
429 | unsafe { self.0.__iterator_get_unchecked(idx) } |
430 | } |
431 | } |
432 | |
433 | #[stable(feature = "case_mapping_double_ended", since = "1.59.0")] |
434 | impl DoubleEndedIterator for $ITER_NAME { |
435 | fn next_back(&mut self) -> Option<char> { |
436 | self.0.next_back() |
437 | } |
438 | |
439 | fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc |
440 | where |
441 | Fold: FnMut(Acc, Self::Item) -> Acc, |
442 | { |
443 | self.0.rfold(init, rfold) |
444 | } |
445 | |
446 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
447 | self.0.advance_back_by(n) |
448 | } |
449 | } |
450 | |
451 | #[stable(feature = "fused", since = "1.26.0")] |
452 | impl FusedIterator for $ITER_NAME {} |
453 | |
454 | #[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] |
455 | impl ExactSizeIterator for $ITER_NAME { |
456 | fn len(&self) -> usize { |
457 | self.0.len() |
458 | } |
459 | |
460 | fn is_empty(&self) -> bool { |
461 | self.0.is_empty() |
462 | } |
463 | } |
464 | |
465 | // SAFETY: forwards to inner `array::IntoIter` |
466 | #[unstable(feature = "trusted_len", issue = "37572")] |
467 | unsafe impl TrustedLen for $ITER_NAME {} |
468 | |
469 | // SAFETY: forwards to inner `array::IntoIter` |
470 | #[doc(hidden)] |
471 | #[unstable(feature = "std_internals", issue = "none")] |
472 | unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME { |
473 | const MAY_HAVE_SIDE_EFFECT: bool = false; |
474 | } |
475 | |
476 | // SAFETY: this iter has no subtypes/supertypes |
477 | #[doc(hidden)] |
478 | #[unstable(feature = "std_internals", issue = "none")] |
479 | unsafe impl TrustedRandomAccess for $ITER_NAME {} |
480 | |
481 | #[stable(feature = "char_struct_display", since = "1.16.0")] |
482 | impl fmt::Display for $ITER_NAME { |
483 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
484 | fmt::Display::fmt(&self.0, f) |
485 | } |
486 | } |
487 | } |
488 | } |
489 | |
490 | casemappingiter_impls! { |
491 | /// Returns an iterator that yields the lowercase equivalent of a `char`. |
492 | /// |
493 | /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See |
494 | /// its documentation for more. |
495 | /// |
496 | /// [`to_lowercase`]: char::to_lowercase |
497 | ToLowercase |
498 | } |
499 | |
500 | casemappingiter_impls! { |
501 | /// Returns an iterator that yields the uppercase equivalent of a `char`. |
502 | /// |
503 | /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See |
504 | /// its documentation for more. |
505 | /// |
506 | /// [`to_uppercase`]: char::to_uppercase |
507 | ToUppercase |
508 | } |
509 | |
510 | #[derive(Debug, Clone)] |
511 | struct CaseMappingIter(core::array::IntoIter<char, 3>); |
512 | |
513 | impl CaseMappingIter { |
514 | #[inline] |
515 | fn new(chars: [char; 3]) -> CaseMappingIter { |
516 | let mut iter: IntoIter |
517 | if chars[2] == '\0 '{ |
518 | iter.next_back(); |
519 | if chars[1] == '\0 '{ |
520 | iter.next_back(); |
521 | |
522 | // Deliberately don't check `chars[0]`, |
523 | // as '\0' lowercases to itself |
524 | } |
525 | } |
526 | CaseMappingIter(iter) |
527 | } |
528 | } |
529 | |
530 | impl Iterator for CaseMappingIter { |
531 | type Item = char; |
532 | |
533 | fn next(&mut self) -> Option<char> { |
534 | self.0.next() |
535 | } |
536 | |
537 | fn size_hint(&self) -> (usize, Option<usize>) { |
538 | self.0.size_hint() |
539 | } |
540 | |
541 | fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
542 | where |
543 | Fold: FnMut(Acc, Self::Item) -> Acc, |
544 | { |
545 | self.0.fold(init, fold) |
546 | } |
547 | |
548 | fn count(self) -> usize { |
549 | self.0.count() |
550 | } |
551 | |
552 | fn last(self) -> Option<Self::Item> { |
553 | self.0.last() |
554 | } |
555 | |
556 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
557 | self.0.advance_by(n) |
558 | } |
559 | |
560 | unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { |
561 | // SAFETY: just forwarding requirements to caller |
562 | unsafe { self.0.__iterator_get_unchecked(idx) } |
563 | } |
564 | } |
565 | |
566 | impl DoubleEndedIterator for CaseMappingIter { |
567 | fn next_back(&mut self) -> Option<char> { |
568 | self.0.next_back() |
569 | } |
570 | |
571 | fn rfold<Acc, Fold>(self, init: Acc, rfold: Fold) -> Acc |
572 | where |
573 | Fold: FnMut(Acc, Self::Item) -> Acc, |
574 | { |
575 | self.0.rfold(init, f:rfold) |
576 | } |
577 | |
578 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
579 | self.0.advance_back_by(n) |
580 | } |
581 | } |
582 | |
583 | impl ExactSizeIterator for CaseMappingIter { |
584 | fn len(&self) -> usize { |
585 | self.0.len() |
586 | } |
587 | |
588 | fn is_empty(&self) -> bool { |
589 | self.0.is_empty() |
590 | } |
591 | } |
592 | |
593 | impl FusedIterator for CaseMappingIter {} |
594 | |
595 | // SAFETY: forwards to inner `array::IntoIter` |
596 | unsafe impl TrustedLen for CaseMappingIter {} |
597 | |
598 | // SAFETY: forwards to inner `array::IntoIter` |
599 | unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter { |
600 | const MAY_HAVE_SIDE_EFFECT: bool = false; |
601 | } |
602 | |
603 | // SAFETY: `CaseMappingIter` has no subtypes/supertypes |
604 | unsafe impl TrustedRandomAccess for CaseMappingIter {} |
605 | |
606 | impl fmt::Display for CaseMappingIter { |
607 | #[inline] |
608 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
609 | for c: char in self.0.clone() { |
610 | f.write_char(c)?; |
611 | } |
612 | Ok(()) |
613 | } |
614 | } |
615 | |
616 | /// The error type returned when a checked char conversion fails. |
617 | #[stable(feature = "u8_from_char", since = "1.59.0")] |
618 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
619 | pub struct TryFromCharError(pub(crate) ()); |
620 | |
621 | #[stable(feature = "u8_from_char", since = "1.59.0")] |
622 | impl fmt::Display for TryFromCharError { |
623 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
624 | "unicode code point out of range".fmt(fmt) |
625 | } |
626 | } |
627 | |
628 | #[stable(feature = "u8_from_char", since = "1.59.0")] |
629 | impl Error for TryFromCharError {} |
630 |
Definitions
- decode_utf16
- from_u32
- from_u32_unchecked
- from_digit
- EscapeUnicode
- new
- Item
- next
- size_hint
- count
- last
- advance_by
- len
- fmt
- EscapeDefault
- printable
- backslash
- unicode
- Item
- next
- size_hint
- count
- last
- advance_by
- len
- fmt
- EscapeDebug
- EscapeDebugInner
- Bytes
- Char
- printable
- backslash
- unicode
- clear
- Item
- next
- size_hint
- count
- len
- fmt
- casemappingiter_impls
- ToLowercase
- ToUppercase
- CaseMappingIter
- new
- Item
- next
- size_hint
- fold
- count
- last
- advance_by
- __iterator_get_unchecked
- next_back
- rfold
- advance_back_by
- len
- is_empty
- fmt
- TryFromCharError
Learn Rust with the experts
Find out more