Skip to main content

qubit_codec_text/charset/
unicode.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8/// Namespace for Unicode constants and encoding-independent code point helpers.
9pub enum Unicode {}
10
11impl Unicode {
12    /// Maximum valid Unicode code point.
13    pub const MAX_CODE_POINT: u32 = 0x10ffff;
14
15    /// Unicode replacement character.
16    pub const REPLACEMENT_CHARACTER: char = '\u{fffd}';
17
18    /// Unicode byte order mark character.
19    pub const BOM: char = '\u{feff}';
20
21    /// Maximum valid ASCII code point.
22    pub const ASCII_MAX: u32 = 0x7f;
23
24    /// Maximum valid Latin-1 code point.
25    pub const LATIN1_MAX: u32 = 0xff;
26
27    /// Minimum supplementary code point.
28    pub const SUPPLEMENTARY_MIN: u32 = 0x10000;
29
30    /// Minimum high-surrogate code unit value.
31    pub const HIGH_SURROGATE_MIN: u32 = 0xd800;
32
33    /// Maximum high-surrogate code unit value.
34    pub const HIGH_SURROGATE_MAX: u32 = 0xdbff;
35
36    /// Minimum low-surrogate code unit value.
37    pub const LOW_SURROGATE_MIN: u32 = 0xdc00;
38
39    /// Maximum low-surrogate code unit value.
40    pub const LOW_SURROGATE_MAX: u32 = 0xdfff;
41
42    /// Minimum surrogate code unit value.
43    pub const SURROGATE_MIN: u32 = Self::HIGH_SURROGATE_MIN;
44
45    /// Maximum surrogate code unit value.
46    pub const SURROGATE_MAX: u32 = Self::LOW_SURROGATE_MAX;
47
48    /// Tests whether `value` is in the Unicode code point range.
49    ///
50    /// # Parameters
51    ///
52    /// - `value`: The raw code point value to test.
53    ///
54    /// # Returns
55    ///
56    /// Returns `true` for values in `0x0000..=0x10FFFF`, including surrogate
57    /// code points.
58    #[inline(always)]
59    pub const fn is_code_point(value: u32) -> bool {
60        value <= Self::MAX_CODE_POINT
61    }
62
63    /// Tests whether `value` is a valid Unicode scalar value.
64    ///
65    /// # Parameters
66    ///
67    /// - `value`: The raw code point value to test.
68    ///
69    /// # Returns
70    ///
71    /// Returns `true` for Unicode code points excluding UTF-16 surrogate
72    /// values.
73    #[inline(always)]
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(always)]
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(always)]
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(always)]
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(always)]
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(always)]
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(always)]
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(always)]
173    pub const fn is_noncharacter(value: u32) -> bool {
174        Self::is_code_point(value)
175            && ((value >= 0xfdd0 && value <= 0xfdef)
176                || (value & 0xfffe) == 0xfffe)
177    }
178
179    /// Tests whether `value` is a Unicode C0, C1, or DEL control code point.
180    ///
181    /// # Parameters
182    ///
183    /// - `value`: The raw code point value to test.
184    ///
185    /// # Returns
186    ///
187    /// Returns `true` for `U+0000..=U+001F`, `U+007F`, and `U+0080..=U+009F`.
188    #[inline(always)]
189    pub const fn is_control(value: u32) -> bool {
190        value <= 0x1f || (value >= 0x7f && value <= 0x9f)
191    }
192
193    /// Returns the Unicode plane containing `value`.
194    ///
195    /// # Parameters
196    ///
197    /// - `value`: The raw code point value to inspect.
198    ///
199    /// # Returns
200    ///
201    /// Returns `Some(plane)` for Unicode code points, or `None` for values
202    /// above `U+10FFFF`.
203    #[inline(always)]
204    pub const fn plane(value: u32) -> Option<u32> {
205        if Self::is_code_point(value) {
206            Some(value >> 16)
207        } else {
208            None
209        }
210    }
211
212    /// Converts a raw code point into a Rust `char`.
213    ///
214    /// # Parameters
215    ///
216    /// - `value`: The raw code point value to convert.
217    ///
218    /// # Returns
219    ///
220    /// Returns `Some(char)` for valid Unicode scalar values and `None`
221    /// otherwise.
222    #[inline(always)]
223    pub fn to_char(value: u32) -> Option<char> {
224        char::from_u32(value)
225    }
226}