Skip to main content

qubit_text_codec/charset/
unicode.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10/// Namespace for Unicode constants and encoding-independent code point helpers.
11pub enum Unicode {}
12
13impl Unicode {
14    /// Maximum valid Unicode code point.
15    pub const MAX_CODE_POINT: u32 = 0x10ffff;
16
17    /// Unicode replacement character.
18    pub const REPLACEMENT_CHARACTER: char = '\u{fffd}';
19
20    /// Unicode byte order mark character.
21    pub const BOM: char = '\u{feff}';
22
23    /// Maximum valid ASCII code point.
24    pub const ASCII_MAX: u32 = 0x7f;
25
26    /// Maximum valid Latin-1 code point.
27    pub const LATIN1_MAX: u32 = 0xff;
28
29    /// Minimum supplementary code point.
30    pub const SUPPLEMENTARY_MIN: u32 = 0x10000;
31
32    /// Minimum high-surrogate code unit value.
33    pub const HIGH_SURROGATE_MIN: u32 = 0xd800;
34
35    /// Maximum high-surrogate code unit value.
36    pub const HIGH_SURROGATE_MAX: u32 = 0xdbff;
37
38    /// Minimum low-surrogate code unit value.
39    pub const LOW_SURROGATE_MIN: u32 = 0xdc00;
40
41    /// Maximum low-surrogate code unit value.
42    pub const LOW_SURROGATE_MAX: u32 = 0xdfff;
43
44    /// Minimum surrogate code unit value.
45    pub const SURROGATE_MIN: u32 = Self::HIGH_SURROGATE_MIN;
46
47    /// Maximum surrogate code unit value.
48    pub const SURROGATE_MAX: u32 = Self::LOW_SURROGATE_MAX;
49
50    /// Tests whether `value` is in the Unicode code point range.
51    ///
52    /// # Parameters
53    ///
54    /// - `value`: The raw code point value to test.
55    ///
56    /// # Returns
57    ///
58    /// Returns `true` for values in `0x0000..=0x10FFFF`, including surrogate code points.
59    #[inline]
60    pub const fn is_code_point(value: u32) -> bool {
61        value <= Self::MAX_CODE_POINT
62    }
63
64    /// Tests whether `value` is a valid Unicode scalar value.
65    ///
66    /// # Parameters
67    ///
68    /// - `value`: The raw code point value to test.
69    ///
70    /// # Returns
71    ///
72    /// Returns `true` for Unicode code points excluding UTF-16 surrogate values.
73    #[inline]
74    pub const fn is_scalar_value(value: u32) -> bool {
75        Self::is_code_point(value) && !Self::is_surrogate(value)
76    }
77
78    /// Tests whether `value` is a UTF-16 surrogate code point.
79    ///
80    /// # Parameters
81    ///
82    /// - `value`: The raw code point or code-unit value to test.
83    ///
84    /// # Returns
85    ///
86    /// Returns `true` if `value` is in `0xD800..=0xDFFF`.
87    #[inline]
88    pub const fn is_surrogate(value: u32) -> bool {
89        value >= Self::SURROGATE_MIN && value <= Self::SURROGATE_MAX
90    }
91
92    /// Tests whether `value` is a high surrogate.
93    ///
94    /// # Parameters
95    ///
96    /// - `value`: The raw code point or code-unit value to test.
97    ///
98    /// # Returns
99    ///
100    /// Returns `true` if `value` is in `0xD800..=0xDBFF`.
101    #[inline]
102    pub const fn is_high_surrogate(value: u32) -> bool {
103        value >= Self::HIGH_SURROGATE_MIN && value <= Self::HIGH_SURROGATE_MAX
104    }
105
106    /// Tests whether `value` is a low surrogate.
107    ///
108    /// # Parameters
109    ///
110    /// - `value`: The raw code point or code-unit value to test.
111    ///
112    /// # Returns
113    ///
114    /// Returns `true` if `value` is in `0xDC00..=0xDFFF`.
115    #[inline]
116    pub const fn is_low_surrogate(value: u32) -> bool {
117        value >= Self::LOW_SURROGATE_MIN && value <= Self::LOW_SURROGATE_MAX
118    }
119
120    /// Tests whether `value` is in the basic multilingual plane.
121    ///
122    /// # Parameters
123    ///
124    /// - `value`: The raw code point value to test.
125    ///
126    /// # Returns
127    ///
128    /// Returns `true` if `value` is in `0x0000..=0xFFFF`.
129    #[inline]
130    pub const fn is_bmp(value: u32) -> bool {
131        value < Self::SUPPLEMENTARY_MIN
132    }
133
134    /// Tests whether `value` is a supplementary Unicode code point.
135    ///
136    /// # Parameters
137    ///
138    /// - `value`: The raw code point value to test.
139    ///
140    /// # Returns
141    ///
142    /// Returns `true` if `value` is in `0x10000..=0x10FFFF`.
143    #[inline]
144    pub const fn is_supplementary(value: u32) -> bool {
145        value >= Self::SUPPLEMENTARY_MIN && value <= Self::MAX_CODE_POINT
146    }
147
148    /// Tests whether `value` is an ASCII code point.
149    ///
150    /// # Parameters
151    ///
152    /// - `value`: The raw code point value to test.
153    ///
154    /// # Returns
155    ///
156    /// Returns `true` if `value` is in `0x00..=0x7F`.
157    #[inline]
158    pub const fn is_ascii(value: u32) -> bool {
159        value <= Self::ASCII_MAX
160    }
161
162    /// Tests whether `value` is a Unicode noncharacter.
163    ///
164    /// # Parameters
165    ///
166    /// - `value`: The raw code point value to test.
167    ///
168    /// # Returns
169    ///
170    /// Returns `true` for Unicode noncharacters such as `U+FDD0..=U+FDEF` and
171    /// code points ending in `FFFE` or `FFFF`.
172    #[inline]
173    pub const fn is_noncharacter(value: u32) -> bool {
174        Self::is_code_point(value) && ((value >= 0xfdd0 && value <= 0xfdef) || (value & 0xfffe) == 0xfffe)
175    }
176
177    /// Tests whether `value` is a Unicode C0, C1, or DEL control code point.
178    ///
179    /// # Parameters
180    ///
181    /// - `value`: The raw code point value to test.
182    ///
183    /// # Returns
184    ///
185    /// Returns `true` for `U+0000..=U+001F`, `U+007F`, and `U+0080..=U+009F`.
186    #[inline]
187    pub const fn is_control(value: u32) -> bool {
188        value <= 0x1f || (value >= 0x7f && value <= 0x9f)
189    }
190
191    /// Returns the Unicode plane containing `value`.
192    ///
193    /// # Parameters
194    ///
195    /// - `value`: The raw code point value to inspect.
196    ///
197    /// # Returns
198    ///
199    /// Returns `Some(plane)` for Unicode code points, or `None` for values above
200    /// `U+10FFFF`.
201    #[inline]
202    pub const fn plane(value: u32) -> Option<u32> {
203        if Self::is_code_point(value) {
204            Some(value >> 16)
205        } else {
206            None
207        }
208    }
209
210    /// Converts a raw code point into a Rust `char`.
211    ///
212    /// # Parameters
213    ///
214    /// - `value`: The raw code point value to convert.
215    ///
216    /// # Returns
217    ///
218    /// Returns `Some(char)` for valid Unicode scalar values and `None` otherwise.
219    #[inline]
220    pub fn to_char(value: u32) -> Option<char> {
221        char::from_u32(value)
222    }
223}