devela/text/char/impls/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// devela::text::char::impls
//
//!
//
// TOC
// - specific implementations
// - common implementations

#[allow(unused_imports)]
use super::*; // char*

/* specific implementations */

mod c;
#[cfg(feature = "_char16")]
mod c16;
#[cfg(feature = "_char7")]
mod c7;
#[cfg(feature = "_char8")]
mod c8;

/* common implementations */

/// implements `UnicodeScalar` for custom char types.
macro_rules! impl_char {
    () => {
        impl_char![7|"_char7", 8|"_char8", 16|"_char16"];
    };
    ($( $bits:literal | $feature:literal ),+ ) => { $crate::paste! {
        $(
            #[cfg(feature = $feature)]
            impl_char!(@[<char $bits>]);
        )+
    }};
    (@$name:ident) => {

        /* impl traits */

        impl UnicodeScalar for $name {
            const MIN: Self = Self::MIN;
            const MAX: Self = Self::MAX;

            /* encode */

            fn byte_len(self) -> usize { self.byte_len() }
            fn len_utf8(self) -> usize { self.len_utf8() }
            fn len_utf16(self) -> usize { self.len_utf16() }
            fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
                self.to_char().encode_utf8(dst)
            }
            fn to_utf8_bytes(self) -> [u8; 4] {
                let dyn_array = self.to_utf8_bytes();
                let mut array = [0u8; 4];
                for i in 0..dyn_array.len() {
                    array[i] = dyn_array[i];
                }
                array
            }
            fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
                self.to_char().encode_utf16(dst)
            }
            fn to_digit(self, radix: u32) -> Option<u32> { self.to_digit(radix) }
            fn to_ascii_uppercase(self) -> Self { self.to_ascii_uppercase() }
            fn to_ascii_lowercase(self) -> Self { self.to_ascii_lowercase() }

            /* queries */

            fn is_noncharacter(self) -> bool { self.is_noncharacter() }
            fn is_digit(self, radix: u32) -> bool { self.is_digit(radix) }
            //
            fn is_control(self) -> bool { self.to_char().is_control() }
            fn is_nul(self) -> bool { self.is_nul() }
            fn is_alphabetic(self) -> bool { self.to_char().is_alphabetic() }
            fn is_numeric(self) -> bool { self.to_char().is_numeric() }
            fn is_alphanumeric(self) -> bool { self.to_char().is_alphanumeric() }
            fn is_lowercase(self) -> bool { self.to_char().is_lowercase() }
            fn is_uppercase(self) -> bool { self.to_char().is_uppercase() }
            fn is_whitespace(self) -> bool { self.to_char().is_whitespace() }
            //
            fn is_ascii(self) -> bool { self.is_ascii() }
        }

        /* impl const fns */

        impl $name {
            /* encode */

            /// Returns the number of bytes needed to represent the scalar value.
            #[must_use]
            pub const fn byte_len(self) -> usize { Char::byte_len(self.to_u32()) }

            /// Returns the number of bytes needed to encode in UTF-8.
            #[must_use]
            pub const fn len_utf8(self) -> usize { self.to_char().len_utf8() }

            /// Returns the number of bytes needed to encode in UTF-16.
            #[must_use]
            pub const fn len_utf16(self) -> usize { self.to_char().len_utf16() }

            /// Converts the scalar to a digit in the given radix.
            ///
            /// ‘Digit’ is defined to be only the following characters:
            /// `0-9`, `a-z`, `A-Z`.
            ///
            /// # Errors
            /// Returns None if the char does not refer to a digit in the given radix.
            ///
            /// # Panics
            /// Panics if given a radix larger than 36.
            #[must_use]
            pub const fn to_digit(self, radix: u32) -> Option<u32> {
                self.to_char().to_digit(radix)
            }

            /* queries */

            /// Returns `true` if this is the nul character (`0x00`).
            #[must_use]
            pub const fn is_nul(self) -> bool { self.to_u32() == 0 }

            /// Checks if the unicode scalar is a digit in the given radix.
            ///
            /// See also [`to_digit`][Self#method.to_digit].
            #[must_use]
            pub const fn is_digit(self, radix: u32) -> bool {
                if let Some(_) = self.to_digit(radix) { true } else { false }
            }
        }
    };
}
impl_char!();