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}