nonzero_char/lib.rs
1#![no_std]
2#![doc = include_str!("../README.md")]
3
4extern crate alloc;
5
6pub mod iter;
7pub mod from_str;
8pub mod convert;
9
10use core::{
11 char::*,
12 cmp::Ordering,
13 fmt::{self, Debug, Display},
14 num::NonZeroU32,
15};
16
17
18#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19#[repr(transparent)]
20pub struct NonZeroChar(NonZeroU32);
21
22impl Debug for NonZeroChar {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 Debug::fmt(&self.get(), f)
25 }
26}
27impl Display for NonZeroChar {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 Display::fmt(&self.get(), f)
30 }
31}
32impl PartialEq<char> for NonZeroChar {
33 fn eq(&self, other: &char) -> bool {
34 self.get() == *other
35 }
36}
37impl PartialEq<NonZeroChar> for char {
38 fn eq(&self, other: &NonZeroChar) -> bool {
39 *self == other.get()
40 }
41}
42impl PartialOrd<char> for NonZeroChar {
43 fn partial_cmp(&self, other: &char) -> Option<Ordering> {
44 self.get().partial_cmp(other)
45 }
46
47 fn lt(&self, other: &char) -> bool {
48 self.get().lt(other)
49 }
50
51 fn le(&self, other: &char) -> bool {
52 self.get().le(other)
53 }
54
55 fn gt(&self, other: &char) -> bool {
56 self.get().gt(other)
57 }
58
59 fn ge(&self, other: &char) -> bool {
60 self.get().ge(other)
61 }
62}
63impl PartialOrd<NonZeroChar> for char {
64 fn partial_cmp(&self, other: &NonZeroChar) -> Option<Ordering> {
65 self.partial_cmp(&other.get())
66 }
67
68 fn lt(&self, other: &NonZeroChar) -> bool {
69 self.lt(&other.get())
70 }
71
72 fn le(&self, other: &NonZeroChar) -> bool {
73 self.le(&other.get())
74 }
75
76 fn gt(&self, other: &NonZeroChar) -> bool {
77 self.gt(&other.get())
78 }
79
80 fn ge(&self, other: &NonZeroChar) -> bool {
81 self.ge(&other.get())
82 }
83}
84
85// The methods and documentation are sourced from
86// [Rust](https://github.com/rust-lang/rust) STD.
87// Some of the documentation and implement has been modified,
88// and most of the methods have been directly forwarded to char
89// Rust uses MIT+APACHE license
90impl NonZeroChar {
91 /// Creates a non-zero if the given value is not zero.
92 ///
93 /// # Examples
94 /// ```
95 /// # use nonzero_char::NonZeroChar;
96 /// assert_eq!(NonZeroChar::new('a').map(NonZeroChar::get), Some('a'));
97 /// assert_eq!(NonZeroChar::new('\0').map(NonZeroChar::get), None);
98 /// ```
99 pub const fn new(ch: char) -> Option<Self> {
100 match NonZeroU32::new(ch as u32) {
101 Some(ch) => Some(Self(ch)),
102 None => None,
103 }
104 }
105
106 /// Creates a non-zero without checking whether the value is non-zero. This results in
107 /// undefined behavior if the value is zero.
108 ///
109 /// # Safety
110 /// The value must not be zero ('\0').
111 pub const unsafe fn new_unchecked(ch: char) -> Self {
112 #[cfg(debug_assertions)]
113 debug_assert!(Self::new(ch).is_some());
114 unsafe {
115 Self(NonZeroU32::new_unchecked(ch as u32))
116 }
117 }
118
119 /// Returns the contained value as a primitive type.
120 pub const fn get(self) -> char {
121 // SAFETY: Assume on create this type
122 unsafe { char::from_u32_unchecked(self.0.get()) }
123 }
124
125 /// Like `self..=max`
126 ///
127 /// # Examples
128 /// ```
129 /// # use nonzero_char::NonZeroChar;
130 /// let mut iter = NonZeroChar::new('a').unwrap()
131 /// .iter_inclusive(NonZeroChar::new('c').unwrap());
132 /// assert_eq!(iter.next(), Some(NonZeroChar::new('a').unwrap()));
133 /// assert_eq!(iter.next(), Some(NonZeroChar::new('b').unwrap()));
134 /// assert_eq!(iter.next(), Some(NonZeroChar::new('c').unwrap()));
135 /// assert_eq!(iter.next(), None);
136 /// ```
137 pub fn iter_inclusive(self, max: Self) -> iter::RangeInclusiveIter {
138 let iter = self.get()..=max.get();
139 iter::RangeInclusiveIter { iter: iter.into_iter() }
140 }
141
142 /// The lowest valid code point a [`NonZeroChar`] can have, `'\x01'`.
143 ///
144 /// Unlike integer types, `char` actually has a gap in the middle,
145 /// meaning that the range of possible `char`s is smaller than you
146 /// might expect. Ranges of `char` will automatically hop this gap
147 /// for you:
148 ///
149 /// ```
150 /// # use nonzero_char::NonZeroChar;
151 /// let dist = u32::from(char::MAX) - u32::from(char::MIN);
152 /// let size = (char::MIN..=char::MAX).count() as u32;
153 /// assert!(size < dist);
154 /// ```
155 ///
156 /// Despite this gap, the `MIN` and [`MAX`] values can be used as bounds for
157 /// all `char` values.
158 ///
159 /// [`MAX`]: char::MAX
160 ///
161 /// # Examples
162 ///
163 /// ```
164 /// # use nonzero_char::NonZeroChar;
165 /// # fn something_which_returns_char() -> char { 'a' }
166 /// let c: char = something_which_returns_char();
167 /// assert!(char::MIN <= c);
168 ///
169 /// let value_at_min = u32::from(NonZeroChar::MIN);
170 /// assert_eq!(char::from_u32(value_at_min), Some('\x01'));
171 /// ```
172 pub const MIN: Self = Self::new('\x01').unwrap();
173
174 /// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
175 ///
176 /// Unlike integer types, `char` actually has a gap in the middle,
177 /// meaning that the range of possible `char`s is smaller than you
178 /// might expect. Ranges of `char` will automatically hop this gap
179 /// for you:
180 ///
181 /// ```
182 /// # use nonzero_char::NonZeroChar;
183 /// let dist = u32::from(NonZeroChar::MAX) - u32::from(NonZeroChar::MIN);
184 /// let size = NonZeroChar::MIN.iter_inclusive(NonZeroChar::MAX).count() as u32;
185 /// assert!(size < dist);
186 /// ```
187 ///
188 /// Despite this gap, the [`MIN`] and `MAX` values can be used as bounds for
189 /// all `char` values.
190 ///
191 /// [`MIN`]: NonZeroChar::MIN
192 ///
193 /// # Examples
194 ///
195 /// ```
196 /// # use nonzero_char::NonZeroChar;
197 /// # fn something_which_returns_char() -> char { 'a' }
198 /// let c: char = something_which_returns_char();
199 /// assert!(c <= char::MAX);
200 ///
201 /// let value_at_max = u32::from(NonZeroChar::MAX);
202 /// assert_eq!(char::from_u32(value_at_max), Some('\u{10FFFF}'));
203 /// assert_eq!(NonZeroChar::from_u32(value_at_max + 1), None);
204 /// ```
205 pub const MAX: Self = Self::new('\u{10FFFF}').unwrap();
206
207 /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a
208 /// decoding error.
209 ///
210 /// It can occur, for example, when giving ill-formed UTF-8 bytes to
211 /// [`String::from_utf8_lossy`](alloc::string::String::from_utf8_lossy).
212 pub const REPLACEMENT_CHARACTER: Self = Self::new('\u{FFFD}').unwrap();
213
214 /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
215 /// `char` and `str` methods are based on.
216 ///
217 /// New versions of Unicode are released regularly and subsequently all methods
218 /// in the standard library depending on Unicode are updated. Therefore the
219 /// behavior of some `char` and `str` methods and the value of this constant
220 /// changes over time. This is *not* considered to be a breaking change.
221 ///
222 /// The version numbering scheme is explained in
223 /// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4).
224 pub const UNICODE_VERSION: (u8, u8, u8) = char::UNICODE_VERSION;
225
226 /// Creates an iterator over the native endian UTF-16 encoded code points in `iter`,
227 /// returning unpaired surrogates as `Err`s.
228 ///
229 /// # Examples
230 ///
231 /// Basic usage:
232 ///
233 /// ```
234 /// # use nonzero_char::NonZeroChar;
235 /// // 𝄞mus<invalid>ic<invalid>
236 /// let v = [
237 /// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
238 /// ];
239 ///
240 /// assert_eq!(
241 /// char::decode_utf16(v)
242 /// .map(|r| r.map_err(|e| e.unpaired_surrogate()))
243 /// .collect::<Vec<_>>(),
244 /// vec![
245 /// Ok('𝄞'),
246 /// Ok('m'), Ok('u'), Ok('s'),
247 /// Err(0xDD1E),
248 /// Ok('i'), Ok('c'),
249 /// Err(0xD834)
250 /// ]
251 /// );
252 /// ```
253 ///
254 /// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
255 ///
256 /// ```
257 /// # use nonzero_char::NonZeroChar;
258 /// // 𝄞mus<invalid>ic<invalid>
259 /// let v = [
260 /// 0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
261 /// ];
262 ///
263 /// assert_eq!(
264 /// char::decode_utf16(v)
265 /// .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
266 /// .collect::<String>(),
267 /// "𝄞mus�ic�"
268 /// );
269 /// ```
270 #[inline]
271 pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
272 char::decode_utf16(iter)
273 }
274
275 /// Converts a `NonZeroChar` to a `NonZeroU32`
276 ///
277 /// # Examples
278 /// ```
279 /// # use nonzero_char::NonZeroChar;
280 /// # use core::num::NonZeroU32;
281 /// let ch = NonZeroChar::new('\x1b').unwrap();
282 /// let num = NonZeroU32::new(0x1b).unwrap();
283 /// assert_eq!(ch.as_nonzero_u32(), num);
284 /// ```
285 pub fn as_nonzero_u32(self) -> NonZeroU32 {
286 self.0
287 }
288
289 /// Converts a `NonZeroChar` to a `u32`
290 ///
291 /// # Examples
292 /// ```
293 /// # use nonzero_char::NonZeroChar;
294 /// # use core::num::NonZeroU32;
295 /// let ch = NonZeroChar::new('\x1b').unwrap();
296 /// assert_eq!(ch.as_u32(), 0x1b);
297 /// ```
298 pub fn as_u32(self) -> u32 {
299 self.as_nonzero_u32().get()
300 }
301
302 /// Converts a `u32` to a `NonZeroChar`.
303 ///
304 /// Note that all `NonZeroChar`s are valid [`u32`]s,
305 /// and can be cast to one with [`as_u32`](#method.as_u32):
306 ///
307 /// ```
308 /// # use nonzero_char::NonZeroChar;
309 /// let c = '💯';
310 /// let i = c as u32;
311 ///
312 /// assert_eq!(128175, i);
313 /// ```
314 ///
315 /// However, the reverse is not true: not all valid [`u32`]s are valid
316 /// `char`s. `from_u32()` will return `None` if the input is not a valid value
317 /// for a `char`.
318 ///
319 /// For an unsafe version of this function which ignores these checks, see
320 /// [`from_u32_unchecked`].
321 ///
322 /// [`from_u32_unchecked`]: #method.from_u32_unchecked
323 ///
324 /// # Examples
325 ///
326 /// Basic usage:
327 ///
328 /// ```
329 /// # use nonzero_char::NonZeroChar;
330 /// let c = NonZeroChar::from_u32(0x2764);
331 ///
332 /// assert_eq!(Some(NonZeroChar::new('❤').unwrap()), c);
333 /// ```
334 ///
335 /// Returning `None` when the input is not a valid `char`:
336 ///
337 /// ```
338 /// # use nonzero_char::NonZeroChar;
339 /// let c = NonZeroChar::from_u32(0x110000);
340 ///
341 /// assert_eq!(None, c);
342 /// ```
343 ///
344 /// Returning `None` when the input by zero:
345 ///
346 /// ```
347 /// # use nonzero_char::NonZeroChar;
348 /// let c = NonZeroChar::from_u32(0);
349 ///
350 /// assert_eq!(None, c);
351 /// ```
352 #[must_use]
353 #[inline]
354 pub const fn from_u32(i: u32) -> Option<Self> {
355 match char::from_u32(i) {
356 Some(ch) => Self::new(ch),
357 None => None,
358 }
359 }
360
361 /// Converts a `u32` to a `char`, ignoring validity.
362 ///
363 /// Note that all `char`s are valid [`u32`]s, and can be cast to one with
364 /// `as`:
365 ///
366 /// ```
367 /// # use nonzero_char::NonZeroChar;
368 /// let c = '💯';
369 /// let i = c as u32;
370 ///
371 /// assert_eq!(128175, i);
372 /// ```
373 ///
374 /// However, the reverse is not true: not all valid [`u32`]s are valid
375 /// `char`s. `from_u32_unchecked()` will ignore this, and blindly cast to
376 /// `char`, possibly creating an invalid one.
377 ///
378 /// # Safety
379 ///
380 /// This function is unsafe, as it may construct invalid `char` values.
381 ///
382 /// For a safe version of this function, see the [`from_u32`] function.
383 ///
384 /// [`from_u32`]: #method.from_u32
385 ///
386 /// # Examples
387 ///
388 /// Basic usage:
389 ///
390 /// ```
391 /// # use nonzero_char::NonZeroChar;
392 /// let c = unsafe { NonZeroChar::from_u32_unchecked(0x2764) };
393 ///
394 /// assert_eq!(NonZeroChar::new('❤').unwrap(), c);
395 /// ```
396 #[must_use]
397 #[inline]
398 pub const unsafe fn from_u32_unchecked(i: u32) -> Self {
399 unsafe {
400 Self(NonZeroU32::new_unchecked(i))
401 }
402 }
403
404 /// Converts a digit in the given radix to a `char`.
405 ///
406 /// A 'radix' here is sometimes also called a 'base'. A radix of two
407 /// indicates a binary number, a radix of ten, decimal, and a radix of
408 /// sixteen, hexadecimal, to give some common values. Arbitrary
409 /// radices are supported.
410 ///
411 /// `from_digit()` will return `None` if the input is not a digit in
412 /// the given radix.
413 ///
414 /// # Panics
415 ///
416 /// Panics if given a radix larger than 36.
417 ///
418 /// # Examples
419 ///
420 /// Basic usage:
421 ///
422 /// ```
423 /// # use nonzero_char::NonZeroChar;
424 /// let c = NonZeroChar::from_digit(4, 10);
425 /// let d = NonZeroChar::new('4').unwrap();
426 ///
427 /// assert_eq!(Some(d), c);
428 ///
429 /// // Decimal 11 is a single digit in base 16
430 /// let c = NonZeroChar::from_digit(11, 16);
431 /// let d = NonZeroChar::new('b').unwrap();
432 ///
433 /// assert_eq!(Some(d), c);
434 /// ```
435 ///
436 /// Returning `None` when the input is not a digit:
437 ///
438 /// ```
439 /// # use nonzero_char::NonZeroChar;
440 /// let c = NonZeroChar::from_digit(20, 10);
441 ///
442 /// assert_eq!(None, c);
443 /// ```
444 ///
445 /// Passing a large radix, causing a panic:
446 ///
447 /// ```should_panic
448 /// # use nonzero_char::NonZeroChar;
449 /// // this panics
450 /// let _c = NonZeroChar::from_digit(1, 37);
451 /// ```
452 #[must_use]
453 #[inline]
454 pub const fn from_digit(num: u32, radix: u32) -> Option<Self> {
455 match char::from_digit(num, radix) {
456 Some(ch) => {
457 // SAFETY: Digit != '\0'
458 unsafe { Some(Self::new_unchecked(ch)) }
459 },
460 None => None,
461 }
462 }
463
464 /// Checks if a `char` is a digit in the given radix.
465 ///
466 /// A 'radix' here is sometimes also called a 'base'. A radix of two
467 /// indicates a binary number, a radix of ten, decimal, and a radix of
468 /// sixteen, hexadecimal, to give some common values. Arbitrary
469 /// radices are supported.
470 ///
471 /// Compared to [`is_numeric()`], this function only recognizes the characters
472 /// `0-9`, `a-z` and `A-Z`.
473 ///
474 /// 'Digit' is defined to be only the following characters:
475 ///
476 /// * `0-9`
477 /// * `a-z`
478 /// * `A-Z`
479 ///
480 /// For a more comprehensive understanding of 'digit', see [`is_numeric()`].
481 ///
482 /// [`is_numeric()`]: #method.is_numeric
483 ///
484 /// # Panics
485 ///
486 /// Panics if given a radix smaller than 2 or larger than 36.
487 ///
488 /// # Examples
489 ///
490 /// Basic usage:
491 ///
492 /// ```
493 /// # use nonzero_char::NonZeroChar;
494 /// assert!('1'.is_digit(10));
495 /// assert!('f'.is_digit(16));
496 /// assert!(!'f'.is_digit(10));
497 /// ```
498 ///
499 /// Passing a large radix, causing a panic:
500 ///
501 /// ```should_panic
502 /// # use nonzero_char::NonZeroChar;
503 /// // this panics
504 /// '1'.is_digit(37);
505 /// ```
506 ///
507 /// Passing a small radix, causing a panic:
508 ///
509 /// ```should_panic
510 /// # use nonzero_char::NonZeroChar;
511 /// // this panics
512 /// '1'.is_digit(1);
513 /// ```
514 #[inline]
515 pub fn is_digit(self, radix: u32) -> bool {
516 self.get().is_digit(radix)
517 }
518
519 /// Converts a `char` to a digit in the given radix.
520 ///
521 /// A 'radix' here is sometimes also called a 'base'. A radix of two
522 /// indicates a binary number, a radix of ten, decimal, and a radix of
523 /// sixteen, hexadecimal, to give some common values. Arbitrary
524 /// radices are supported.
525 ///
526 /// 'Digit' is defined to be only the following characters:
527 ///
528 /// * `0-9`
529 /// * `a-z`
530 /// * `A-Z`
531 ///
532 /// # Errors
533 ///
534 /// Returns `None` if the `char` does not refer to a digit in the given radix.
535 ///
536 /// # Panics
537 ///
538 /// Panics if given a radix smaller than 2 or larger than 36.
539 ///
540 /// # Examples
541 ///
542 /// Basic usage:
543 ///
544 /// ```
545 /// # use nonzero_char::NonZeroChar;
546 /// assert_eq!('1'.to_digit(10), Some(1));
547 /// assert_eq!('f'.to_digit(16), Some(15));
548 /// ```
549 ///
550 /// Passing a non-digit results in failure:
551 ///
552 /// ```
553 /// # use nonzero_char::NonZeroChar;
554 /// assert_eq!('f'.to_digit(10), None);
555 /// assert_eq!('z'.to_digit(16), None);
556 /// ```
557 ///
558 /// Passing a large radix, causing a panic:
559 ///
560 /// ```should_panic
561 /// # use nonzero_char::NonZeroChar;
562 /// // this panics
563 /// let _ = '1'.to_digit(37);
564 /// ```
565 /// Passing a small radix, causing a panic:
566 ///
567 /// ```should_panic
568 /// # use nonzero_char::NonZeroChar;
569 /// // this panics
570 /// let _ = '1'.to_digit(1);
571 /// ```
572 #[must_use = "this returns the result of the operation, \
573 without modifying the original"]
574 #[inline]
575 pub const fn to_digit(self, radix: u32) -> Option<u32> {
576 self.get().to_digit(radix)
577 }
578
579 /// Returns an iterator that yields the hexadecimal Unicode escape of a
580 /// character as `char`s.
581 ///
582 /// This will escape characters with the Rust syntax of the form
583 /// `\u{NNNNNN}` where `NNNNNN` is a hexadecimal representation.
584 ///
585 /// # Examples
586 ///
587 /// As an iterator:
588 ///
589 /// ```
590 /// # use nonzero_char::NonZeroChar;
591 /// for c in '❤'.escape_unicode() {
592 /// print!("{c}");
593 /// }
594 /// println!();
595 /// ```
596 ///
597 /// Using `println!` directly:
598 ///
599 /// ```
600 /// # use nonzero_char::NonZeroChar;
601 /// println!("{}", '❤'.escape_unicode());
602 /// ```
603 ///
604 /// Both are equivalent to:
605 ///
606 /// ```
607 /// # use nonzero_char::NonZeroChar;
608 /// println!("\\u{{2764}}");
609 /// ```
610 ///
611 /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
612 ///
613 /// ```
614 /// # use nonzero_char::NonZeroChar;
615 /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
616 /// ```
617 #[must_use = "this returns the escaped char as an iterator, \
618 without modifying the original"]
619 #[inline]
620 pub fn escape_unicode(self) -> EscapeUnicode {
621 self.get().escape_unicode()
622 }
623
624 /// Returns an iterator that yields the literal escape code of a character
625 /// as `char`s.
626 ///
627 /// This will escape the characters similar to the [`Debug`] implementations
628 /// of `str` or `char`.
629 ///
630 /// # Examples
631 ///
632 /// As an iterator:
633 ///
634 /// ```
635 /// # use nonzero_char::NonZeroChar;
636 /// for c in '\n'.escape_debug() {
637 /// print!("{c}");
638 /// }
639 /// println!();
640 /// ```
641 ///
642 /// Using `println!` directly:
643 ///
644 /// ```
645 /// # use nonzero_char::NonZeroChar;
646 /// println!("{}", '\n'.escape_debug());
647 /// ```
648 ///
649 /// Both are equivalent to:
650 ///
651 /// ```
652 /// # use nonzero_char::NonZeroChar;
653 /// println!("\\n");
654 /// ```
655 ///
656 /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
657 ///
658 /// ```
659 /// # use nonzero_char::NonZeroChar;
660 /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
661 /// ```
662 #[must_use = "this returns the escaped char as an iterator, \
663 without modifying the original"]
664 #[inline]
665 pub fn escape_debug(self) -> EscapeDebug {
666 self.get().escape_debug()
667 }
668
669 /// Returns an iterator that yields the literal escape code of a character
670 /// as `char`s.
671 ///
672 /// The default is chosen with a bias toward producing literals that are
673 /// legal in a variety of languages, including C++11 and similar C-family
674 /// languages. The exact rules are:
675 ///
676 /// * Tab is escaped as `\t`.
677 /// * Carriage return is escaped as `\r`.
678 /// * Line feed is escaped as `\n`.
679 /// * Single quote is escaped as `\'`.
680 /// * Double quote is escaped as `\"`.
681 /// * Backslash is escaped as `\\`.
682 /// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
683 /// inclusive is not escaped.
684 /// * All other characters are given hexadecimal Unicode escapes; see
685 /// [`escape_unicode`].
686 ///
687 /// [`escape_unicode`]: #method.escape_unicode
688 ///
689 /// # Examples
690 ///
691 /// As an iterator:
692 ///
693 /// ```
694 /// # use nonzero_char::NonZeroChar;
695 /// for c in '"'.escape_default() {
696 /// print!("{c}");
697 /// }
698 /// println!();
699 /// ```
700 ///
701 /// Using `println!` directly:
702 ///
703 /// ```
704 /// # use nonzero_char::NonZeroChar;
705 /// println!("{}", '"'.escape_default());
706 /// ```
707 ///
708 /// Both are equivalent to:
709 ///
710 /// ```
711 /// # use nonzero_char::NonZeroChar;
712 /// println!("\\\"");
713 /// ```
714 ///
715 /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
716 ///
717 /// ```
718 /// # use nonzero_char::NonZeroChar;
719 /// assert_eq!('"'.escape_default().to_string(), "\\\"");
720 /// ```
721 #[must_use = "this returns the escaped char as an iterator, \
722 without modifying the original"]
723 #[inline]
724 pub fn escape_default(self) -> EscapeDefault {
725 self.get().escape_default()
726 }
727
728 /// Returns the number of bytes this `char` would need if encoded in UTF-8.
729 ///
730 /// That number of bytes is always between 1 and 4, inclusive.
731 ///
732 /// # Examples
733 ///
734 /// Basic usage:
735 ///
736 /// ```
737 /// # use nonzero_char::NonZeroChar;
738 /// let len = 'A'.len_utf8();
739 /// assert_eq!(len, 1);
740 ///
741 /// let len = 'ß'.len_utf8();
742 /// assert_eq!(len, 2);
743 ///
744 /// let len = 'ℝ'.len_utf8();
745 /// assert_eq!(len, 3);
746 ///
747 /// let len = '💣'.len_utf8();
748 /// assert_eq!(len, 4);
749 /// ```
750 ///
751 /// The `&str` type guarantees that its contents are UTF-8, and so we can compare the length it
752 /// would take if each code point was represented as a `char` vs in the `&str` itself:
753 ///
754 /// ```
755 /// # use nonzero_char::NonZeroChar;
756 /// // as chars
757 /// let eastern = '東';
758 /// let capital = '京';
759 ///
760 /// // both can be represented as three bytes
761 /// assert_eq!(3, eastern.len_utf8());
762 /// assert_eq!(3, capital.len_utf8());
763 ///
764 /// // as a &str, these two are encoded in UTF-8
765 /// let tokyo = "東京";
766 ///
767 /// let len = eastern.len_utf8() + capital.len_utf8();
768 ///
769 /// // we can see that they take six bytes total...
770 /// assert_eq!(6, tokyo.len());
771 ///
772 /// // ... just like the &str
773 /// assert_eq!(len, tokyo.len());
774 /// ```
775 #[inline]
776 #[must_use]
777 pub const fn len_utf8(self) -> usize {
778 self.get().len_utf8()
779 }
780
781 /// Returns the number of 16-bit code units this `char` would need if
782 /// encoded in UTF-16.
783 ///
784 /// That number of code units is always either 1 or 2, for unicode scalar values in
785 /// the [basic multilingual plane] or [supplementary planes] respectively.
786 ///
787 /// See the documentation for [`len_utf8()`] for more explanation of this
788 /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
789 ///
790 /// [basic multilingual plane]: http://www.unicode.org/glossary/#basic_multilingual_plane
791 /// [supplementary planes]: http://www.unicode.org/glossary/#supplementary_planes
792 /// [`len_utf8()`]: #method.len_utf8
793 ///
794 /// # Examples
795 ///
796 /// Basic usage:
797 ///
798 /// ```
799 /// # use nonzero_char::NonZeroChar;
800 /// let n = 'ß'.len_utf16();
801 /// assert_eq!(n, 1);
802 ///
803 /// let len = '💣'.len_utf16();
804 /// assert_eq!(len, 2);
805 /// ```
806 #[inline]
807 #[must_use]
808 pub const fn len_utf16(self) -> usize {
809 self.get().len_utf16()
810 }
811
812 /// Encodes this character as UTF-8 into the provided byte buffer,
813 /// and then returns the subslice of the buffer that contains the encoded character.
814 ///
815 /// # Panics
816 ///
817 /// Panics if the buffer is not large enough.
818 /// A buffer of length four is large enough to encode any `char`.
819 ///
820 /// # Examples
821 ///
822 /// In both of these examples, 'ß' takes two bytes to encode.
823 ///
824 /// ```
825 /// # use nonzero_char::NonZeroChar;
826 /// let mut b = [0; 2];
827 ///
828 /// let result = 'ß'.encode_utf8(&mut b);
829 ///
830 /// assert_eq!(result, "ß");
831 ///
832 /// assert_eq!(result.len(), 2);
833 /// ```
834 ///
835 /// A buffer that's too small:
836 ///
837 /// ```should_panic
838 /// # use nonzero_char::NonZeroChar;
839 /// let mut b = [0; 1];
840 ///
841 /// // this panics
842 /// 'ß'.encode_utf8(&mut b);
843 /// ```
844 #[inline]
845 pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
846 self.get().encode_utf8(dst)
847 }
848
849 /// Encodes this character as native endian UTF-16 into the provided `u16` buffer,
850 /// and then returns the subslice of the buffer that contains the encoded character.
851 ///
852 /// # Panics
853 ///
854 /// Panics if the buffer is not large enough.
855 /// A buffer of length 2 is large enough to encode any `char`.
856 ///
857 /// # Examples
858 ///
859 /// In both of these examples, '𝕊' takes two `u16`s to encode.
860 ///
861 /// ```
862 /// # use nonzero_char::NonZeroChar;
863 /// let mut b = [0; 2];
864 ///
865 /// let result = '𝕊'.encode_utf16(&mut b);
866 ///
867 /// assert_eq!(result.len(), 2);
868 /// ```
869 ///
870 /// A buffer that's too small:
871 ///
872 /// ```should_panic
873 /// # use nonzero_char::NonZeroChar;
874 /// let mut b = [0; 1];
875 ///
876 /// // this panics
877 /// '𝕊'.encode_utf16(&mut b);
878 /// ```
879 #[inline]
880 pub const fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
881 self.get().encode_utf16(dst)
882 }
883
884 /// Returns `true` if this `char` has the `Alphabetic` property.
885 ///
886 /// `Alphabetic` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
887 /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
888 ///
889 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
890 /// [ucd]: https://www.unicode.org/reports/tr44/
891 /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
892 ///
893 /// # Examples
894 ///
895 /// Basic usage:
896 ///
897 /// ```
898 /// # use nonzero_char::NonZeroChar;
899 /// assert!('a'.is_alphabetic());
900 /// assert!('京'.is_alphabetic());
901 ///
902 /// let c = '💝';
903 /// // love is many things, but it is not alphabetic
904 /// assert!(!c.is_alphabetic());
905 /// ```
906 #[must_use]
907 #[inline]
908 pub fn is_alphabetic(self) -> bool {
909 self.get().is_alphabetic()
910 }
911
912 /// Returns `true` if this `char` has the `Lowercase` property.
913 ///
914 /// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
915 /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
916 ///
917 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
918 /// [ucd]: https://www.unicode.org/reports/tr44/
919 /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
920 ///
921 /// # Examples
922 ///
923 /// Basic usage:
924 ///
925 /// ```
926 /// # use nonzero_char::NonZeroChar;
927 /// assert!('a'.is_lowercase());
928 /// assert!('δ'.is_lowercase());
929 /// assert!(!'A'.is_lowercase());
930 /// assert!(!'Δ'.is_lowercase());
931 ///
932 /// // The various Chinese scripts and punctuation do not have case, and so:
933 /// assert!(!'中'.is_lowercase());
934 /// assert!(!' '.is_lowercase());
935 /// ```
936 ///
937 /// In a const context:
938 ///
939 /// ```
940 /// # use nonzero_char::NonZeroChar;
941 /// const CAPITAL_DELTA_IS_LOWERCASE: bool = 'Δ'.is_lowercase();
942 /// assert!(!CAPITAL_DELTA_IS_LOWERCASE);
943 /// ```
944 #[must_use]
945 #[inline]
946 pub const fn is_lowercase(self) -> bool {
947 self.get().is_lowercase()
948 }
949
950 /// Returns `true` if this `char` has the `Uppercase` property.
951 ///
952 /// `Uppercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and
953 /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`].
954 ///
955 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
956 /// [ucd]: https://www.unicode.org/reports/tr44/
957 /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
958 ///
959 /// # Examples
960 ///
961 /// Basic usage:
962 ///
963 /// ```
964 /// # use nonzero_char::NonZeroChar;
965 /// assert!(!'a'.is_uppercase());
966 /// assert!(!'δ'.is_uppercase());
967 /// assert!('A'.is_uppercase());
968 /// assert!('Δ'.is_uppercase());
969 ///
970 /// // The various Chinese scripts and punctuation do not have case, and so:
971 /// assert!(!'中'.is_uppercase());
972 /// assert!(!' '.is_uppercase());
973 /// ```
974 ///
975 /// In a const context:
976 ///
977 /// ```
978 /// # use nonzero_char::NonZeroChar;
979 /// const CAPITAL_DELTA_IS_UPPERCASE: bool = 'Δ'.is_uppercase();
980 /// assert!(CAPITAL_DELTA_IS_UPPERCASE);
981 /// ```
982 #[must_use]
983 #[inline]
984 pub const fn is_uppercase(self) -> bool {
985 self.get().is_uppercase()
986 }
987
988 /// Returns `true` if this `char` has the `White_Space` property.
989 ///
990 /// `White_Space` is specified in the [Unicode Character Database][ucd] [`PropList.txt`].
991 ///
992 /// [ucd]: https://www.unicode.org/reports/tr44/
993 /// [`PropList.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt
994 ///
995 /// # Examples
996 ///
997 /// Basic usage:
998 ///
999 /// ```
1000 /// # use nonzero_char::NonZeroChar;
1001 /// assert!(' '.is_whitespace());
1002 ///
1003 /// // line break
1004 /// assert!('\n'.is_whitespace());
1005 ///
1006 /// // a non-breaking space
1007 /// assert!('\u{A0}'.is_whitespace());
1008 ///
1009 /// assert!(!'越'.is_whitespace());
1010 /// ```
1011 #[must_use]
1012 #[inline]
1013 pub fn is_whitespace(self) -> bool {
1014 self.get().is_whitespace()
1015 }
1016
1017 /// Returns `true` if this `char` satisfies either [`is_alphabetic()`] or [`is_numeric()`].
1018 ///
1019 /// [`is_alphabetic()`]: #method.is_alphabetic
1020 /// [`is_numeric()`]: #method.is_numeric
1021 ///
1022 /// # Examples
1023 ///
1024 /// Basic usage:
1025 ///
1026 /// ```
1027 /// # use nonzero_char::NonZeroChar;
1028 /// assert!('٣'.is_alphanumeric());
1029 /// assert!('7'.is_alphanumeric());
1030 /// assert!('৬'.is_alphanumeric());
1031 /// assert!('¾'.is_alphanumeric());
1032 /// assert!('①'.is_alphanumeric());
1033 /// assert!('K'.is_alphanumeric());
1034 /// assert!('و'.is_alphanumeric());
1035 /// assert!('藏'.is_alphanumeric());
1036 /// ```
1037 #[must_use]
1038 #[inline]
1039 pub fn is_alphanumeric(self) -> bool {
1040 self.get().is_alphanumeric()
1041 }
1042
1043 /// Returns `true` if this `char` has the general category for control codes.
1044 ///
1045 /// Control codes (code points with the general category of `Cc`) are described in Chapter 4
1046 /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character
1047 /// Database][ucd] [`UnicodeData.txt`].
1048 ///
1049 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1050 /// [ucd]: https://www.unicode.org/reports/tr44/
1051 /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1052 ///
1053 /// # Examples
1054 ///
1055 /// Basic usage:
1056 ///
1057 /// ```
1058 /// # use nonzero_char::NonZeroChar;
1059 /// // U+009C, STRING TERMINATOR
1060 /// assert!(''.is_control());
1061 /// assert!(!'q'.is_control());
1062 /// ```
1063 #[must_use]
1064 #[inline]
1065 pub fn is_control(self) -> bool {
1066 self.get().is_control()
1067 }
1068
1069 /// Returns `true` if this `char` has one of the general categories for numbers.
1070 ///
1071 /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
1072 /// characters, and `No` for other numeric characters) are specified in the [Unicode Character
1073 /// Database][ucd] [`UnicodeData.txt`].
1074 ///
1075 /// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'.
1076 /// If you want everything including characters with overlapping purposes then you might want to use
1077 /// a unicode or language-processing library that exposes the appropriate character properties instead
1078 /// of looking at the unicode categories.
1079 ///
1080 /// If you want to parse ASCII decimal digits (0-9) or ASCII base-N, use
1081 /// `is_ascii_digit` or `is_digit` instead.
1082 ///
1083 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1084 /// [ucd]: https://www.unicode.org/reports/tr44/
1085 /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1086 ///
1087 /// # Examples
1088 ///
1089 /// Basic usage:
1090 ///
1091 /// ```
1092 /// # use nonzero_char::NonZeroChar;
1093 /// assert!('٣'.is_numeric());
1094 /// assert!('7'.is_numeric());
1095 /// assert!('৬'.is_numeric());
1096 /// assert!('¾'.is_numeric());
1097 /// assert!('①'.is_numeric());
1098 /// assert!(!'K'.is_numeric());
1099 /// assert!(!'و'.is_numeric());
1100 /// assert!(!'藏'.is_numeric());
1101 /// assert!(!'三'.is_numeric());
1102 /// ```
1103 #[must_use]
1104 #[inline]
1105 pub fn is_numeric(self) -> bool {
1106 self.get().is_numeric()
1107 }
1108
1109 /// Returns an iterator that yields the lowercase mapping of this `char` as one or more
1110 /// `char`s.
1111 ///
1112 /// If this `char` does not have a lowercase mapping, the iterator yields the same `char`.
1113 ///
1114 /// If this `char` has a one-to-one lowercase mapping given by the [Unicode Character
1115 /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
1116 ///
1117 /// [ucd]: https://www.unicode.org/reports/tr44/
1118 /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1119 ///
1120 /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
1121 /// the `char`(s) given by [`SpecialCasing.txt`].
1122 ///
1123 /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
1124 ///
1125 /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1126 /// is independent of context and language.
1127 ///
1128 /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1129 /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1130 ///
1131 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1132 ///
1133 /// # Examples
1134 ///
1135 /// As an iterator:
1136 ///
1137 /// ```
1138 /// # use nonzero_char::NonZeroChar;
1139 /// for c in 'İ'.to_lowercase() {
1140 /// print!("{c}");
1141 /// }
1142 /// println!();
1143 /// ```
1144 ///
1145 /// Using `println!` directly:
1146 ///
1147 /// ```
1148 /// # use nonzero_char::NonZeroChar;
1149 /// println!("{}", 'İ'.to_lowercase());
1150 /// ```
1151 ///
1152 /// Both are equivalent to:
1153 ///
1154 /// ```
1155 /// # use nonzero_char::NonZeroChar;
1156 /// println!("i\u{307}");
1157 /// ```
1158 ///
1159 /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1160 ///
1161 /// ```
1162 /// # use nonzero_char::NonZeroChar;
1163 /// assert_eq!('C'.to_lowercase().to_string(), "c");
1164 ///
1165 /// // Sometimes the result is more than one character:
1166 /// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
1167 ///
1168 /// // Characters that do not have both uppercase and lowercase
1169 /// // convert into themselves.
1170 /// assert_eq!('山'.to_lowercase().to_string(), "山");
1171 /// ```
1172 #[must_use = "this returns the lowercase character as a new iterator, \
1173 without modifying the original"]
1174 #[inline]
1175 pub fn to_lowercase(self) -> ToLowercase {
1176 self.get().to_lowercase()
1177 }
1178
1179 /// Returns an iterator that yields the uppercase mapping of this `char` as one or more
1180 /// `char`s.
1181 ///
1182 /// If this `char` does not have an uppercase mapping, the iterator yields the same `char`.
1183 ///
1184 /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character
1185 /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`.
1186 ///
1187 /// [ucd]: https://www.unicode.org/reports/tr44/
1188 /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
1189 ///
1190 /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields
1191 /// the `char`(s) given by [`SpecialCasing.txt`].
1192 ///
1193 /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
1194 ///
1195 /// This operation performs an unconditional mapping without tailoring. That is, the conversion
1196 /// is independent of context and language.
1197 ///
1198 /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in
1199 /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion.
1200 ///
1201 /// [Unicode Standard]: https://www.unicode.org/versions/latest/
1202 ///
1203 /// # Examples
1204 ///
1205 /// As an iterator:
1206 ///
1207 /// ```
1208 /// # use nonzero_char::NonZeroChar;
1209 /// for c in 'ß'.to_uppercase() {
1210 /// print!("{c}");
1211 /// }
1212 /// println!();
1213 /// ```
1214 ///
1215 /// Using `println!` directly:
1216 ///
1217 /// ```
1218 /// # use nonzero_char::NonZeroChar;
1219 /// println!("{}", 'ß'.to_uppercase());
1220 /// ```
1221 ///
1222 /// Both are equivalent to:
1223 ///
1224 /// ```
1225 /// # use nonzero_char::NonZeroChar;
1226 /// println!("SS");
1227 /// ```
1228 ///
1229 /// Using [`to_string`](../std/string/trait.ToString.html#tymethod.to_string):
1230 ///
1231 /// ```
1232 /// # use nonzero_char::NonZeroChar;
1233 /// assert_eq!('c'.to_uppercase().to_string(), "C");
1234 ///
1235 /// // Sometimes the result is more than one character:
1236 /// assert_eq!('ß'.to_uppercase().to_string(), "SS");
1237 ///
1238 /// // Characters that do not have both uppercase and lowercase
1239 /// // convert into themselves.
1240 /// assert_eq!('山'.to_uppercase().to_string(), "山");
1241 /// ```
1242 ///
1243 /// # Note on locale
1244 ///
1245 /// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
1246 ///
1247 /// * 'Dotless': I / ı, sometimes written ï
1248 /// * 'Dotted': İ / i
1249 ///
1250 /// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
1251 ///
1252 /// ```
1253 /// # use nonzero_char::NonZeroChar;
1254 /// let upper_i = 'i'.to_uppercase().to_string();
1255 /// ```
1256 ///
1257 /// The value of `upper_i` here relies on the language of the text: if we're
1258 /// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
1259 /// be `"İ"`. `to_uppercase()` does not take this into account, and so:
1260 ///
1261 /// ```
1262 /// # use nonzero_char::NonZeroChar;
1263 /// let upper_i = 'i'.to_uppercase().to_string();
1264 ///
1265 /// assert_eq!(upper_i, "I");
1266 /// ```
1267 ///
1268 /// holds across languages.
1269 #[must_use = "this returns the uppercase character as a new iterator, \
1270 without modifying the original"]
1271 #[inline]
1272 pub fn to_uppercase(self) -> ToUppercase {
1273 self.get().to_uppercase()
1274 }
1275
1276 /// Checks if the value is within the ASCII range.
1277 ///
1278 /// # Examples
1279 ///
1280 /// ```
1281 /// # use nonzero_char::NonZeroChar;
1282 /// let ascii = 'a';
1283 /// let non_ascii = '❤';
1284 ///
1285 /// assert!(ascii.is_ascii());
1286 /// assert!(!non_ascii.is_ascii());
1287 /// ```
1288 #[must_use]
1289 #[inline]
1290 pub const fn is_ascii(&self) -> bool {
1291 self.get().is_ascii()
1292 }
1293
1294 /// Makes a copy of the value in its ASCII upper case equivalent.
1295 ///
1296 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1297 /// but non-ASCII letters are unchanged.
1298 ///
1299 /// To uppercase the value in-place, use [`make_ascii_uppercase()`].
1300 ///
1301 /// To uppercase ASCII characters in addition to non-ASCII characters, use
1302 /// [`to_uppercase()`].
1303 ///
1304 /// # Examples
1305 ///
1306 /// ```
1307 /// # use nonzero_char::NonZeroChar;
1308 /// let ascii = 'a';
1309 /// let non_ascii = '❤';
1310 ///
1311 /// assert_eq!('A', ascii.to_ascii_uppercase());
1312 /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
1313 /// ```
1314 ///
1315 /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase
1316 /// [`to_uppercase()`]: #method.to_uppercase
1317 #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
1318 #[inline]
1319 pub const fn to_ascii_uppercase(&self) -> Self {
1320 let ch = self.get().to_ascii_uppercase();
1321 // SAFETY: only '\0'.to_ascii_uppercase() is '\0'
1322 unsafe { Self::new_unchecked(ch) }
1323 }
1324
1325 /// Makes a copy of the value in its ASCII lower case equivalent.
1326 ///
1327 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1328 /// but non-ASCII letters are unchanged.
1329 ///
1330 /// To lowercase the value in-place, use [`make_ascii_lowercase()`].
1331 ///
1332 /// To lowercase ASCII characters in addition to non-ASCII characters, use
1333 /// [`to_lowercase()`].
1334 ///
1335 /// # Examples
1336 ///
1337 /// ```
1338 /// # use nonzero_char::NonZeroChar;
1339 /// let ascii = 'A';
1340 /// let non_ascii = '❤';
1341 ///
1342 /// assert_eq!('a', ascii.to_ascii_lowercase());
1343 /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
1344 /// ```
1345 ///
1346 /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase
1347 /// [`to_lowercase()`]: #method.to_lowercase
1348 #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
1349 #[inline]
1350 pub const fn to_ascii_lowercase(&self) -> Self {
1351 let ch = self.get().to_ascii_lowercase();
1352 // SAFETY: only '\0'.to_ascii_lowercase() is '\0'
1353 unsafe { Self::new_unchecked(ch) }
1354 }
1355
1356 /// Checks that two values are an ASCII case-insensitive match.
1357 ///
1358 /// Equivalent to <code>[to_ascii_lowercase]\(a) == [to_ascii_lowercase]\(b)</code>.
1359 ///
1360 /// # Examples
1361 ///
1362 /// ```
1363 /// # use nonzero_char::NonZeroChar;
1364 /// let upper_a = 'A';
1365 /// let lower_a = 'a';
1366 /// let lower_z = 'z';
1367 ///
1368 /// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
1369 /// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
1370 /// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
1371 /// ```
1372 ///
1373 /// [to_ascii_lowercase]: #method.to_ascii_lowercase
1374 #[inline]
1375 pub const fn eq_ignore_ascii_case(&self, other: &char) -> bool {
1376 self.get().eq_ignore_ascii_case(other)
1377 }
1378
1379 /// Converts this type to its ASCII upper case equivalent in-place.
1380 ///
1381 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
1382 /// but non-ASCII letters are unchanged.
1383 ///
1384 /// To return a new uppercased value without modifying the existing one, use
1385 /// [`to_ascii_uppercase()`].
1386 ///
1387 /// # Examples
1388 ///
1389 /// ```
1390 /// # use nonzero_char::NonZeroChar;
1391 /// let mut ascii = 'a';
1392 ///
1393 /// ascii.make_ascii_uppercase();
1394 ///
1395 /// assert_eq!('A', ascii);
1396 /// ```
1397 ///
1398 /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase
1399 #[inline]
1400 pub const fn make_ascii_uppercase(&mut self) {
1401 let mut ch = self.get();
1402 ch.make_ascii_uppercase();
1403 // SAFETY: only '\0' upper is '\0'
1404 *self = unsafe { Self::new_unchecked(ch) }
1405 }
1406
1407 /// Converts this type to its ASCII lower case equivalent in-place.
1408 ///
1409 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
1410 /// but non-ASCII letters are unchanged.
1411 ///
1412 /// To return a new lowercased value without modifying the existing one, use
1413 /// [`to_ascii_lowercase()`].
1414 ///
1415 /// # Examples
1416 ///
1417 /// ```
1418 /// # use nonzero_char::NonZeroChar;
1419 /// let mut ascii = 'A';
1420 ///
1421 /// ascii.make_ascii_lowercase();
1422 ///
1423 /// assert_eq!('a', ascii);
1424 /// ```
1425 ///
1426 /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase
1427 #[inline]
1428 pub const fn make_ascii_lowercase(&mut self) {
1429 let mut ch = self.get();
1430 ch.make_ascii_lowercase();
1431 // SAFETY: only '\0' lower is '\0'
1432 *self = unsafe { Self::new_unchecked(ch) }
1433 }
1434
1435 /// Checks if the value is an ASCII alphabetic character:
1436 ///
1437 /// - U+0041 'A' ..= U+005A 'Z', or
1438 /// - U+0061 'a' ..= U+007A 'z'.
1439 ///
1440 /// # Examples
1441 ///
1442 /// ```
1443 /// # use nonzero_char::NonZeroChar;
1444 /// let uppercase_a = 'A';
1445 /// let uppercase_g = 'G';
1446 /// let a = 'a';
1447 /// let g = 'g';
1448 /// let zero = '0';
1449 /// let percent = '%';
1450 /// let space = ' ';
1451 /// let lf = '\n';
1452 /// let esc = '\x1b';
1453 ///
1454 /// assert!(uppercase_a.is_ascii_alphabetic());
1455 /// assert!(uppercase_g.is_ascii_alphabetic());
1456 /// assert!(a.is_ascii_alphabetic());
1457 /// assert!(g.is_ascii_alphabetic());
1458 /// assert!(!zero.is_ascii_alphabetic());
1459 /// assert!(!percent.is_ascii_alphabetic());
1460 /// assert!(!space.is_ascii_alphabetic());
1461 /// assert!(!lf.is_ascii_alphabetic());
1462 /// assert!(!esc.is_ascii_alphabetic());
1463 /// ```
1464 #[must_use]
1465 #[inline]
1466 pub const fn is_ascii_alphabetic(&self) -> bool {
1467 self.get().is_ascii_alphabetic()
1468 }
1469
1470 /// Checks if the value is an ASCII uppercase character:
1471 /// U+0041 'A' ..= U+005A 'Z'.
1472 ///
1473 /// # Examples
1474 ///
1475 /// ```
1476 /// # use nonzero_char::NonZeroChar;
1477 /// let uppercase_a = 'A';
1478 /// let uppercase_g = 'G';
1479 /// let a = 'a';
1480 /// let g = 'g';
1481 /// let zero = '0';
1482 /// let percent = '%';
1483 /// let space = ' ';
1484 /// let lf = '\n';
1485 /// let esc = '\x1b';
1486 ///
1487 /// assert!(uppercase_a.is_ascii_uppercase());
1488 /// assert!(uppercase_g.is_ascii_uppercase());
1489 /// assert!(!a.is_ascii_uppercase());
1490 /// assert!(!g.is_ascii_uppercase());
1491 /// assert!(!zero.is_ascii_uppercase());
1492 /// assert!(!percent.is_ascii_uppercase());
1493 /// assert!(!space.is_ascii_uppercase());
1494 /// assert!(!lf.is_ascii_uppercase());
1495 /// assert!(!esc.is_ascii_uppercase());
1496 /// ```
1497 #[must_use]
1498 #[inline]
1499 pub const fn is_ascii_uppercase(&self) -> bool {
1500 self.get().is_ascii_uppercase()
1501 }
1502
1503 /// Checks if the value is an ASCII lowercase character:
1504 /// U+0061 'a' ..= U+007A 'z'.
1505 ///
1506 /// # Examples
1507 ///
1508 /// ```
1509 /// # use nonzero_char::NonZeroChar;
1510 /// let uppercase_a = 'A';
1511 /// let uppercase_g = 'G';
1512 /// let a = 'a';
1513 /// let g = 'g';
1514 /// let zero = '0';
1515 /// let percent = '%';
1516 /// let space = ' ';
1517 /// let lf = '\n';
1518 /// let esc = '\x1b';
1519 ///
1520 /// assert!(!uppercase_a.is_ascii_lowercase());
1521 /// assert!(!uppercase_g.is_ascii_lowercase());
1522 /// assert!(a.is_ascii_lowercase());
1523 /// assert!(g.is_ascii_lowercase());
1524 /// assert!(!zero.is_ascii_lowercase());
1525 /// assert!(!percent.is_ascii_lowercase());
1526 /// assert!(!space.is_ascii_lowercase());
1527 /// assert!(!lf.is_ascii_lowercase());
1528 /// assert!(!esc.is_ascii_lowercase());
1529 /// ```
1530 #[must_use]
1531 #[inline]
1532 pub const fn is_ascii_lowercase(&self) -> bool {
1533 self.get().is_ascii_lowercase()
1534 }
1535
1536 /// Checks if the value is an ASCII alphanumeric character:
1537 ///
1538 /// - U+0041 'A' ..= U+005A 'Z', or
1539 /// - U+0061 'a' ..= U+007A 'z', or
1540 /// - U+0030 '0' ..= U+0039 '9'.
1541 ///
1542 /// # Examples
1543 ///
1544 /// ```
1545 /// # use nonzero_char::NonZeroChar;
1546 /// let uppercase_a = 'A';
1547 /// let uppercase_g = 'G';
1548 /// let a = 'a';
1549 /// let g = 'g';
1550 /// let zero = '0';
1551 /// let percent = '%';
1552 /// let space = ' ';
1553 /// let lf = '\n';
1554 /// let esc = '\x1b';
1555 ///
1556 /// assert!(uppercase_a.is_ascii_alphanumeric());
1557 /// assert!(uppercase_g.is_ascii_alphanumeric());
1558 /// assert!(a.is_ascii_alphanumeric());
1559 /// assert!(g.is_ascii_alphanumeric());
1560 /// assert!(zero.is_ascii_alphanumeric());
1561 /// assert!(!percent.is_ascii_alphanumeric());
1562 /// assert!(!space.is_ascii_alphanumeric());
1563 /// assert!(!lf.is_ascii_alphanumeric());
1564 /// assert!(!esc.is_ascii_alphanumeric());
1565 /// ```
1566 #[must_use]
1567 #[inline]
1568 pub const fn is_ascii_alphanumeric(&self) -> bool {
1569 self.get().is_ascii_alphanumeric()
1570 }
1571
1572 /// Checks if the value is an ASCII decimal digit:
1573 /// U+0030 '0' ..= U+0039 '9'.
1574 ///
1575 /// # Examples
1576 ///
1577 /// ```
1578 /// # use nonzero_char::NonZeroChar;
1579 /// let uppercase_a = 'A';
1580 /// let uppercase_g = 'G';
1581 /// let a = 'a';
1582 /// let g = 'g';
1583 /// let zero = '0';
1584 /// let percent = '%';
1585 /// let space = ' ';
1586 /// let lf = '\n';
1587 /// let esc = '\x1b';
1588 ///
1589 /// assert!(!uppercase_a.is_ascii_digit());
1590 /// assert!(!uppercase_g.is_ascii_digit());
1591 /// assert!(!a.is_ascii_digit());
1592 /// assert!(!g.is_ascii_digit());
1593 /// assert!(zero.is_ascii_digit());
1594 /// assert!(!percent.is_ascii_digit());
1595 /// assert!(!space.is_ascii_digit());
1596 /// assert!(!lf.is_ascii_digit());
1597 /// assert!(!esc.is_ascii_digit());
1598 /// ```
1599 #[must_use]
1600 #[inline]
1601 pub const fn is_ascii_digit(&self) -> bool {
1602 self.get().is_ascii_digit()
1603 }
1604
1605 /// Checks if the value is an ASCII hexadecimal digit:
1606 ///
1607 /// - U+0030 '0' ..= U+0039 '9', or
1608 /// - U+0041 'A' ..= U+0046 'F', or
1609 /// - U+0061 'a' ..= U+0066 'f'.
1610 ///
1611 /// # Examples
1612 ///
1613 /// ```
1614 /// # use nonzero_char::NonZeroChar;
1615 /// let uppercase_a = 'A';
1616 /// let uppercase_g = 'G';
1617 /// let a = 'a';
1618 /// let g = 'g';
1619 /// let zero = '0';
1620 /// let percent = '%';
1621 /// let space = ' ';
1622 /// let lf = '\n';
1623 /// let esc = '\x1b';
1624 ///
1625 /// assert!(uppercase_a.is_ascii_hexdigit());
1626 /// assert!(!uppercase_g.is_ascii_hexdigit());
1627 /// assert!(a.is_ascii_hexdigit());
1628 /// assert!(!g.is_ascii_hexdigit());
1629 /// assert!(zero.is_ascii_hexdigit());
1630 /// assert!(!percent.is_ascii_hexdigit());
1631 /// assert!(!space.is_ascii_hexdigit());
1632 /// assert!(!lf.is_ascii_hexdigit());
1633 /// assert!(!esc.is_ascii_hexdigit());
1634 /// ```
1635 #[must_use]
1636 #[inline]
1637 pub const fn is_ascii_hexdigit(&self) -> bool {
1638 self.get().is_ascii_hexdigit()
1639 }
1640
1641 /// Checks if the value is an ASCII punctuation character:
1642 ///
1643 /// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
1644 /// - U+003A ..= U+0040 `: ; < = > ? @`, or
1645 /// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
1646 /// - U+007B ..= U+007E `{ | } ~`
1647 ///
1648 /// # Examples
1649 ///
1650 /// ```
1651 /// # use nonzero_char::NonZeroChar;
1652 /// let uppercase_a = 'A';
1653 /// let uppercase_g = 'G';
1654 /// let a = 'a';
1655 /// let g = 'g';
1656 /// let zero = '0';
1657 /// let percent = '%';
1658 /// let space = ' ';
1659 /// let lf = '\n';
1660 /// let esc = '\x1b';
1661 ///
1662 /// assert!(!uppercase_a.is_ascii_punctuation());
1663 /// assert!(!uppercase_g.is_ascii_punctuation());
1664 /// assert!(!a.is_ascii_punctuation());
1665 /// assert!(!g.is_ascii_punctuation());
1666 /// assert!(!zero.is_ascii_punctuation());
1667 /// assert!(percent.is_ascii_punctuation());
1668 /// assert!(!space.is_ascii_punctuation());
1669 /// assert!(!lf.is_ascii_punctuation());
1670 /// assert!(!esc.is_ascii_punctuation());
1671 /// ```
1672 #[must_use]
1673 #[inline]
1674 pub const fn is_ascii_punctuation(&self) -> bool {
1675 self.get().is_ascii_punctuation()
1676 }
1677
1678 /// Checks if the value is an ASCII graphic character:
1679 /// U+0021 '!' ..= U+007E '~'.
1680 ///
1681 /// # Examples
1682 ///
1683 /// ```
1684 /// # use nonzero_char::NonZeroChar;
1685 /// let uppercase_a = 'A';
1686 /// let uppercase_g = 'G';
1687 /// let a = 'a';
1688 /// let g = 'g';
1689 /// let zero = '0';
1690 /// let percent = '%';
1691 /// let space = ' ';
1692 /// let lf = '\n';
1693 /// let esc = '\x1b';
1694 ///
1695 /// assert!(uppercase_a.is_ascii_graphic());
1696 /// assert!(uppercase_g.is_ascii_graphic());
1697 /// assert!(a.is_ascii_graphic());
1698 /// assert!(g.is_ascii_graphic());
1699 /// assert!(zero.is_ascii_graphic());
1700 /// assert!(percent.is_ascii_graphic());
1701 /// assert!(!space.is_ascii_graphic());
1702 /// assert!(!lf.is_ascii_graphic());
1703 /// assert!(!esc.is_ascii_graphic());
1704 /// ```
1705 #[must_use]
1706 #[inline]
1707 pub const fn is_ascii_graphic(&self) -> bool {
1708 self.get().is_ascii_graphic()
1709 }
1710
1711 /// Checks if the value is an ASCII whitespace character:
1712 /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
1713 /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
1714 ///
1715 /// Rust uses the WhatWG Infra Standard's [definition of ASCII
1716 /// whitespace][infra-aw]. There are several other definitions in
1717 /// wide use. For instance, [the POSIX locale][pct] includes
1718 /// U+000B VERTICAL TAB as well as all the above characters,
1719 /// but—from the very same specification—[the default rule for
1720 /// "field splitting" in the Bourne shell][bfs] considers *only*
1721 /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
1722 ///
1723 /// If you are writing a program that will process an existing
1724 /// file format, check what that format's definition of whitespace is
1725 /// before using this function.
1726 ///
1727 /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
1728 /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
1729 /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
1730 ///
1731 /// # Examples
1732 ///
1733 /// ```
1734 /// # use nonzero_char::NonZeroChar;
1735 /// let uppercase_a = 'A';
1736 /// let uppercase_g = 'G';
1737 /// let a = 'a';
1738 /// let g = 'g';
1739 /// let zero = '0';
1740 /// let percent = '%';
1741 /// let space = ' ';
1742 /// let lf = '\n';
1743 /// let esc = '\x1b';
1744 ///
1745 /// assert!(!uppercase_a.is_ascii_whitespace());
1746 /// assert!(!uppercase_g.is_ascii_whitespace());
1747 /// assert!(!a.is_ascii_whitespace());
1748 /// assert!(!g.is_ascii_whitespace());
1749 /// assert!(!zero.is_ascii_whitespace());
1750 /// assert!(!percent.is_ascii_whitespace());
1751 /// assert!(space.is_ascii_whitespace());
1752 /// assert!(lf.is_ascii_whitespace());
1753 /// assert!(!esc.is_ascii_whitespace());
1754 /// ```
1755 #[must_use]
1756 #[inline]
1757 pub const fn is_ascii_whitespace(&self) -> bool {
1758 self.get().is_ascii_whitespace()
1759 }
1760
1761 /// Checks if the value is an ASCII control character:
1762 /// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
1763 /// Note that most ASCII whitespace characters are control
1764 /// characters, but SPACE is not.
1765 ///
1766 /// # Examples
1767 ///
1768 /// ```
1769 /// # use nonzero_char::NonZeroChar;
1770 /// let uppercase_a = 'A';
1771 /// let uppercase_g = 'G';
1772 /// let a = 'a';
1773 /// let g = 'g';
1774 /// let zero = '0';
1775 /// let percent = '%';
1776 /// let space = ' ';
1777 /// let lf = '\n';
1778 /// let esc = '\x1b';
1779 ///
1780 /// assert!(!uppercase_a.is_ascii_control());
1781 /// assert!(!uppercase_g.is_ascii_control());
1782 /// assert!(!a.is_ascii_control());
1783 /// assert!(!g.is_ascii_control());
1784 /// assert!(!zero.is_ascii_control());
1785 /// assert!(!percent.is_ascii_control());
1786 /// assert!(!space.is_ascii_control());
1787 /// assert!(lf.is_ascii_control());
1788 /// assert!(esc.is_ascii_control());
1789 /// ```
1790 #[must_use]
1791 #[inline]
1792 pub const fn is_ascii_control(&self) -> bool {
1793 self.get().is_ascii_control()
1794 }
1795}
1796
1797#[test]
1798fn test_control_upper() {
1799 let _ = (
1800 NonZeroChar::MIN,
1801 NonZeroChar::MAX,
1802 NonZeroChar::REPLACEMENT_CHARACTER,
1803 NonZeroChar::UNICODE_VERSION,
1804 );
1805 assert_eq!('\x01'.to_ascii_uppercase(), '\x01');
1806}
1807
1808#[test]
1809fn test_npo() {
1810 assert_eq!(size_of::<Option<NonZeroChar>>(), size_of::<NonZeroChar>());
1811}