Skip to main content

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