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