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