1use core::fmt::Formatter;
20use core::num::NonZeroU16;
21
22#[derive(#[automatically_derived]impl ::core::fmt::Debug for Utf16CodeUnitError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Utf16CodeUnitError")
}
}Debug, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
Utf16CodeUnitError {
}
#[automatically_derived]impl ::core::cmp::PartialEq for Utf16CodeUnitError {
#[inline]
fn eq(&self, other: &Self) -> bool { true }
}PartialEq, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Utf16CodeUnitError {
}
#[automatically_derived]impl ::core::clone::Clone for Utf16CodeUnitError {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for Utf16CodeUnitError { }Copy, #[automatically_derived]impl ::core::hash::Hash for Utf16CodeUnitError {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for Utf16CodeUnitError { }Eq)]
24#[non_exhaustive]
25pub struct Utf16CodeUnitError;
26
27impl core::fmt::Display for Utf16CodeUnitError {
28 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
29 f.write_fmt(format_args!("code unit does not fit the requested position in UTF-16"))write!(f, "code unit does not fit the requested position in UTF-16")
30 }
31}
32
33impl core::error::Error for Utf16CodeUnitError {}
34
35macro_rules! surrogate_impl {
36 ($min:expr,
37 $max:expr,
38 $(#[$is_meta:meta])*,
39 $(#[$unchecked_meta:meta])*,
40 $(#[$checked_meta:meta])*,
41 ) => {
42 pub const MIN: Self = const {
44 if $min == 0 {
45 panic!();
46 }
47 Self {
48 code_unit: if let Some(min) = NonZeroU16::new($min) {
49 min
50 } else {
51 panic!();
52 },
53 }
54 };
55
56 pub const MAX: Self = const {
58 Self {
59 code_unit: if let Some(max) = NonZeroU16::new($max) {
60 max
61 } else {
62 panic!();
63 },
64 }
65 };
66
67 $(#[$is_meta])*
68 #[inline(always)]
69 pub const fn is(code_unit: u16) -> bool {
70 code_unit >= Self::MIN.to_u16() && code_unit <= Self::MAX.to_u16()
71 }
72
73 $(#[$unchecked_meta])*
74 #[inline(always)]
75 pub const unsafe fn new_unchecked(code_unit: u16) -> Self {
76 debug_assert!(Self::is(code_unit));
77 Self { code_unit: unsafe { NonZeroU16::new_unchecked(code_unit) } }
81 }
82
83 $(#[$checked_meta])*
84 #[inline(always)]
85 pub const fn try_new(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
86 if Self::is(code_unit) {
87 Ok(unsafe { Self::new_unchecked(code_unit) })
89 } else {
90 Err(Utf16CodeUnitError)
91 }
92 }
93
94 #[inline(always)]
96 pub const fn to_u16(self) -> u16 {
97 self.code_unit.get()
98 }
99 };
100}
101
102macro_rules! to_surrogate {
103 () => {
104 #[inline(always)]
106 pub const fn to_surrogate(self) -> Surrogate {
107 Surrogate {
110 code_unit: self.code_unit,
111 }
112 }
113 };
114}
115
116macro_rules! code_unit_impls {
117 ($type:ident,
118 $type_specific_ident:ident,
119 ) => {
120 impl TryFrom<u16> for $type {
121 type Error = Utf16CodeUnitError;
122
123 #[inline(always)]
124 fn try_from(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
125 Self::try_new(code_unit)
126 }
127 }
128
129 impl From<$type> for u16 {
130 #[inline(always)]
131 fn from($type_specific_ident: $type) -> Self {
132 $type_specific_ident.to_u16()
133 }
134 }
135 };
136}
137
138trait Seal {}
141
142#[allow(private_bounds)] pub trait Utf16CodeUnitSequence: Seal + Copy + Clone + Into<char> + AsRef<[u16]> {}
145
146macro_rules! sequence_impls {
147 ($type:ident,
148 $type_specific_ident:ident,
149 ) => {
150 impl Seal for $type {}
151
152 impl Utf16CodeUnitSequence for $type {}
153
154 impl From<$type> for char {
155 #[inline(always)]
156 fn from($type_specific_ident: $type) -> Self {
157 $type_specific_ident.to_char()
158 }
159 }
160
161 impl AsRef<[u16]> for $type {
162 #[inline(always)]
163 fn as_ref(&self) -> &[u16] {
164 self.as_slice()
165 }
166 }
167 };
168}
169
170#[derive(#[automatically_derived]impl ::core::fmt::Debug for Bmp {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Bmp code_unit",
&&self.code_unit)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Bmp {
}
#[automatically_derived]impl ::core::clone::Clone for Bmp {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<u16>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for Bmp { }Copy, #[automatically_derived]impl ::core::hash::Hash for Bmp {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.code_unit, state)
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for Bmp {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u16>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Bmp { }
#[automatically_derived]impl ::core::cmp::PartialEq for Bmp {
#[inline]
fn eq(&self, other: &Self) -> bool { self.code_unit == other.code_unit }
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for Bmp {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.code_unit, &other.code_unit)
}
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for Bmp {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
173#[repr(transparent)]
174pub struct Bmp {
175 code_unit: u16, }
180
181impl Bmp {
182 #[inline(always)]
189 pub const fn is(code_unit: u16) -> bool {
190 !Surrogate::is(code_unit)
191 }
192
193 #[inline(always)]
204 pub const unsafe fn new_unchecked(code_unit: u16) -> Self {
205 if true {
if !Self::is(code_unit) {
::core::panicking::panic("assertion failed: Self::is(code_unit)")
};
};debug_assert!(Self::is(code_unit));
206 Self { code_unit }
208 }
209
210 #[inline(always)]
214 pub const fn try_new(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
215 if Self::is(code_unit) {
216 Ok(unsafe { Self::new_unchecked(code_unit) })
218 } else {
219 Err(Utf16CodeUnitError)
220 }
221 }
222
223 #[inline(always)]
225 pub const fn to_u16(self) -> u16 {
226 self.code_unit
227 }
228
229 #[inline(always)]
231 pub const fn to_char(self) -> char {
232 let scalar = self.code_unit as u32;
233 if true {
if !char::from_u32(scalar).is_some() {
::core::panicking::panic("assertion failed: char::from_u32(scalar).is_some()")
};
};debug_assert!(char::from_u32(scalar).is_some());
234 unsafe { char::from_u32_unchecked(scalar) }
238 }
239
240 #[inline(always)]
242 pub const fn as_slice(&self) -> &[u16] {
243 core::slice::from_ref(&self.code_unit)
244 }
245}
246
247impl TryFrom<u16> for Bmp {
type Error = Utf16CodeUnitError;
#[inline(always)]
fn try_from(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
Self::try_new(code_unit)
}
}
impl From<Bmp> for u16 {
#[inline(always)]
fn from(bmp: Bmp) -> Self { bmp.to_u16() }
}code_unit_impls!(Bmp, bmp,);
248
249impl Seal for Bmp {}
impl Utf16CodeUnitSequence for Bmp {}
impl From<Bmp> for char {
#[inline(always)]
fn from(bmp: Bmp) -> Self { bmp.to_char() }
}
impl AsRef<[u16]> for Bmp {
#[inline(always)]
fn as_ref(&self) -> &[u16] { self.as_slice() }
}sequence_impls!(Bmp, bmp,);
250
251#[derive(#[automatically_derived]impl ::core::fmt::Debug for Surrogate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Surrogate code_unit", &&self.code_unit)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for Surrogate {
}
#[automatically_derived]impl ::core::clone::Clone for Surrogate {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<NonZeroU16>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for Surrogate { }Copy, #[automatically_derived]impl ::core::hash::Hash for Surrogate {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.code_unit, state)
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for Surrogate {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<NonZeroU16>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for Surrogate
{
}
#[automatically_derived]impl ::core::cmp::PartialEq for Surrogate {
#[inline]
fn eq(&self, other: &Self) -> bool { self.code_unit == other.code_unit }
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for Surrogate {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.code_unit, &other.code_unit)
}
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for Surrogate {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
254#[repr(transparent)]
255pub struct Surrogate {
256 code_unit: NonZeroU16,
260}
261
262impl Surrogate {
263 pub const MIN: Self =
const {
if 0xD800 == 0 { ::core::panicking::panic_default_msg(); }
Self {
code_unit: if let Some(min) = NonZeroU16::new(0xD800) {
min
} else { ::core::panicking::panic_default_msg(); },
}
};
pub const MAX: Self =
const {
Self {
code_unit: if let Some(max) = NonZeroU16::new(0xDFFF) {
max
} else { ::core::panicking::panic_default_msg(); },
}
};
#[doc = r" Whether `code_unit` is a surrogate."]
#[doc = r""]
#[doc = r" # Safety-usable invariant"]
#[doc = r""]
#[doc =
r" Iff this method returns `true`, the safety invariant of `new_unchecked()`"]
#[doc = r" is satisfied."]
#[inline(always)]
pub const fn is(code_unit: u16) -> bool {
code_unit >= Self::MIN.to_u16() && code_unit <= Self::MAX.to_u16()
}
#[doc = r" Unchecked constructor"]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The caller must ensure that `code_unit` is in the range `0xD800..=0xDFFF`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" When debug assertions are enabled, panics if the safety invariant"]
#[doc = r" is not upheld."]
#[inline(always)]
pub const unsafe fn new_unchecked(code_unit: u16) -> Self {
if true {
if !Self::is(code_unit) {
::core::panicking::panic("assertion failed: Self::is(code_unit)")
};
};
Self { code_unit: unsafe { NonZeroU16::new_unchecked(code_unit) } }
}
#[doc = r" Fallible constructor"]
#[doc = r""]
#[doc = r" `Ok` if surrogate and `Err` otherwise."]
#[inline(always)]
pub const fn try_new(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
if Self::is(code_unit) {
Ok(unsafe { Self::new_unchecked(code_unit) })
} else { Err(Utf16CodeUnitError) }
}
#[inline(always)]
pub const fn to_u16(self) -> u16 { self.code_unit.get() }surrogate_impl!(
264 0xD800,
265 0xDFFF,
266 ,
273 ,
284 ,
288 );
289}
290
291impl TryFrom<u16> for Surrogate {
type Error = Utf16CodeUnitError;
#[inline(always)]
fn try_from(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
Self::try_new(code_unit)
}
}
impl From<Surrogate> for u16 {
#[inline(always)]
fn from(surrogate: Surrogate) -> Self { surrogate.to_u16() }
}code_unit_impls!(Surrogate, surrogate,);
292
293#[derive(#[automatically_derived]impl ::core::fmt::Debug for HighSurrogate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HighSurrogate code_unit", &&self.code_unit)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for HighSurrogate {
}
#[automatically_derived]impl ::core::clone::Clone for HighSurrogate {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<NonZeroU16>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for HighSurrogate { }Copy, #[automatically_derived]impl ::core::hash::Hash for HighSurrogate {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.code_unit, state)
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for HighSurrogate {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<NonZeroU16>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
HighSurrogate {
}
#[automatically_derived]impl ::core::cmp::PartialEq for HighSurrogate {
#[inline]
fn eq(&self, other: &Self) -> bool { self.code_unit == other.code_unit }
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for HighSurrogate {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.code_unit, &other.code_unit)
}
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for HighSurrogate {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
295#[repr(transparent)]
296pub struct HighSurrogate {
297 code_unit: NonZeroU16,
301}
302
303impl HighSurrogate {
304 pub const MIN: Self =
const {
if 0xD800 == 0 { ::core::panicking::panic_default_msg(); }
Self {
code_unit: if let Some(min) = NonZeroU16::new(0xD800) {
min
} else { ::core::panicking::panic_default_msg(); },
}
};
pub const MAX: Self =
const {
Self {
code_unit: if let Some(max) = NonZeroU16::new(0xDBFF) {
max
} else { ::core::panicking::panic_default_msg(); },
}
};
#[doc = r" Whether `code_unit` is a high surrogate."]
#[doc = r""]
#[doc = r" # Safety-usable invariant"]
#[doc = r""]
#[doc =
r" Iff this method returns `true`, the safety invariant of `new_unchecked()`"]
#[doc = r" is satisfied."]
#[inline(always)]
pub const fn is(code_unit: u16) -> bool {
code_unit >= Self::MIN.to_u16() && code_unit <= Self::MAX.to_u16()
}
#[doc = r" Unchecked constructor"]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The caller must ensure that `code_unit` is in the range `0xD800..=0xDBFF`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" When debug assertions are enabled, panics if the safety invariant"]
#[doc = r" is not upheld."]
#[inline(always)]
pub const unsafe fn new_unchecked(code_unit: u16) -> Self {
if true {
if !Self::is(code_unit) {
::core::panicking::panic("assertion failed: Self::is(code_unit)")
};
};
Self { code_unit: unsafe { NonZeroU16::new_unchecked(code_unit) } }
}
#[doc = r" Fallible constructor"]
#[doc = r""]
#[doc = r" `Ok` if high surrogate and `Err` otherwise."]
#[inline(always)]
pub const fn try_new(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
if Self::is(code_unit) {
Ok(unsafe { Self::new_unchecked(code_unit) })
} else { Err(Utf16CodeUnitError) }
}
#[inline(always)]
pub const fn to_u16(self) -> u16 { self.code_unit.get() }surrogate_impl!(
305 0xD800,
306 0xDBFF,
307 ,
314 ,
325 ,
329 );
330
331 #[inline(always)]
pub const fn to_surrogate(self) -> Surrogate {
Surrogate { code_unit: self.code_unit }
}to_surrogate!();
332
333 #[inline(always)]
337 pub const fn try_new_with_surrogate(surrogate: Surrogate) -> Result<Self, Utf16CodeUnitError> {
338 let code_unit = surrogate.to_u16();
339 if code_unit <= Self::MAX.to_u16() {
340 Ok(unsafe { Self::new_unchecked(code_unit) })
343 } else {
344 Err(Utf16CodeUnitError)
345 }
346 }
347}
348
349impl TryFrom<u16> for HighSurrogate {
type Error = Utf16CodeUnitError;
#[inline(always)]
fn try_from(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
Self::try_new(code_unit)
}
}
impl From<HighSurrogate> for u16 {
#[inline(always)]
fn from(high_surrogate: HighSurrogate) -> Self { high_surrogate.to_u16() }
}code_unit_impls!(HighSurrogate, high_surrogate,);
350
351#[derive(#[automatically_derived]impl ::core::fmt::Debug for LowSurrogate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"LowSurrogate code_unit", &&self.code_unit)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for LowSurrogate {
}
#[automatically_derived]impl ::core::clone::Clone for LowSurrogate {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<NonZeroU16>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for LowSurrogate { }Copy, #[automatically_derived]impl ::core::hash::Hash for LowSurrogate {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.code_unit, state)
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for LowSurrogate {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<NonZeroU16>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
LowSurrogate {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LowSurrogate {
#[inline]
fn eq(&self, other: &Self) -> bool { self.code_unit == other.code_unit }
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for LowSurrogate {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.code_unit, &other.code_unit)
}
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for LowSurrogate {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
353#[repr(transparent)]
354pub struct LowSurrogate {
355 code_unit: NonZeroU16,
359}
360
361impl LowSurrogate {
362 pub const MIN: Self =
const {
if 0xDC00 == 0 { ::core::panicking::panic_default_msg(); }
Self {
code_unit: if let Some(min) = NonZeroU16::new(0xDC00) {
min
} else { ::core::panicking::panic_default_msg(); },
}
};
pub const MAX: Self =
const {
Self {
code_unit: if let Some(max) = NonZeroU16::new(0xDFFF) {
max
} else { ::core::panicking::panic_default_msg(); },
}
};
#[doc = r" Whether `code_unit` is a low surrogate."]
#[doc = r""]
#[doc = r" # Safety-usable invariant"]
#[doc = r""]
#[doc =
r" Iff this method returns `true`, the safety invariant of `new_unchecked()`"]
#[doc = r" is satisfied."]
#[inline(always)]
pub const fn is(code_unit: u16) -> bool {
code_unit >= Self::MIN.to_u16() && code_unit <= Self::MAX.to_u16()
}
#[doc = r" Unchecked constructor"]
#[doc = r""]
#[doc = r" # Safety"]
#[doc = r""]
#[doc =
r" The caller must ensure that `code_unit` is in the range `0xDC00..=0xDFFF`."]
#[doc = r""]
#[doc = r" # Panics"]
#[doc = r""]
#[doc = r" When debug assertions are enabled, panics if the safety invariant"]
#[doc = r" is not upheld."]
#[inline(always)]
pub const unsafe fn new_unchecked(code_unit: u16) -> Self {
if true {
if !Self::is(code_unit) {
::core::panicking::panic("assertion failed: Self::is(code_unit)")
};
};
Self { code_unit: unsafe { NonZeroU16::new_unchecked(code_unit) } }
}
#[doc = r" Fallible constructor"]
#[doc = r""]
#[doc = r" `Ok` if low surrogate and `Err` otherwise."]
#[inline(always)]
pub const fn try_new(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
if Self::is(code_unit) {
Ok(unsafe { Self::new_unchecked(code_unit) })
} else { Err(Utf16CodeUnitError) }
}
#[inline(always)]
pub const fn to_u16(self) -> u16 { self.code_unit.get() }surrogate_impl!(
363 0xDC00,
364 0xDFFF,
365 ,
372 ,
383 ,
387 );
388
389 #[inline(always)]
pub const fn to_surrogate(self) -> Surrogate {
Surrogate { code_unit: self.code_unit }
}to_surrogate!();
390
391 #[inline(always)]
395 pub const fn try_new_with_surrogate(surrogate: Surrogate) -> Result<Self, Utf16CodeUnitError> {
396 let code_unit = surrogate.to_u16();
397 if code_unit >= Self::MIN.to_u16() {
398 Ok(unsafe { Self::new_unchecked(code_unit) })
401 } else {
402 Err(Utf16CodeUnitError)
403 }
404 }
405}
406
407impl TryFrom<u16> for LowSurrogate {
type Error = Utf16CodeUnitError;
#[inline(always)]
fn try_from(code_unit: u16) -> Result<Self, Utf16CodeUnitError> {
Self::try_new(code_unit)
}
}
impl From<LowSurrogate> for u16 {
#[inline(always)]
fn from(low_surrogate: LowSurrogate) -> Self { low_surrogate.to_u16() }
}code_unit_impls!(LowSurrogate, low_surrogate,);
408
409#[derive(#[automatically_derived]impl ::core::fmt::Debug for SurrogatePair {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"SurrogatePair high low", &self.high, &&self.low)
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for SurrogatePair {
}
#[automatically_derived]impl ::core::clone::Clone for SurrogatePair {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<HighSurrogate>;
let _: ::core::clone::AssertParamIsClone<LowSurrogate>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for SurrogatePair { }Copy, #[automatically_derived]impl ::core::hash::Hash for SurrogatePair {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.high, state);
::core::hash::Hash::hash(&self.low, state)
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for SurrogatePair {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<HighSurrogate>;
let _: ::core::cmp::AssertParamIsEq<LowSurrogate>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
SurrogatePair {
}
#[automatically_derived]impl ::core::cmp::PartialEq for SurrogatePair {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.high == other.high && self.low == other.low
}
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for SurrogatePair {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.high, &other.high) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.low, &other.low),
cmp => cmp,
}
}
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for SurrogatePair {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
414#[repr(C)]
415pub struct SurrogatePair {
416 high: HighSurrogate,
417 low: LowSurrogate,
418}
419
420impl SurrogatePair {
421 #[inline(always)]
423 pub const fn new(high: HighSurrogate, low: LowSurrogate) -> Self {
424 Self { high, low }
425 }
426
427 #[inline(always)]
429 pub const fn to_typed_code_units(self) -> (HighSurrogate, LowSurrogate) {
430 (self.high, self.low)
431 }
432
433 #[inline(always)]
435 pub const fn to_char(self) -> char {
436 let scalar = ((self.high.to_u16() as u32) << 10) + (self.low.to_u16() as u32)
437 - (((0xD800u32 << 10) - 0x10000u32) + 0xDC00u32);
438 if true {
if !char::from_u32(scalar).is_some() {
::core::panicking::panic("assertion failed: char::from_u32(scalar).is_some()")
};
};debug_assert!(char::from_u32(scalar).is_some());
439 unsafe { char::from_u32_unchecked(scalar) }
442 }
443
444 #[inline(always)]
450 pub const fn as_code_units(&self) -> &[u16; 2] {
451 if core::mem::size_of::<Self>() != core::mem::size_of::<[u16; 2]>() {
452 ::core::panicking::panic_default_msg();panic!();
453 }
454 let ptr: *const Self = core::ptr::from_ref(self);
455 unsafe { &*ptr.cast() }
458 }
459
460 #[inline(always)]
466 pub const fn as_slice(&self) -> &[u16] {
467 self.as_code_units()
468 }
469}
470
471impl Seal for SurrogatePair {}
impl Utf16CodeUnitSequence for SurrogatePair {}
impl From<SurrogatePair> for char {
#[inline(always)]
fn from(surrogate_pair: SurrogatePair) -> Self {
surrogate_pair.to_char()
}
}
impl AsRef<[u16]> for SurrogatePair {
#[inline(always)]
fn as_ref(&self) -> &[u16] { self.as_slice() }
}sequence_impls!(SurrogatePair, surrogate_pair,);
472
473#[derive(#[automatically_derived]impl ::core::fmt::Debug for BmpOrSurrogate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Bmp(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Bmp",
&__self_0),
Self::Surrogate(__self_0) =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Surrogate", &__self_0),
}
}
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for BmpOrSurrogate {
}
#[automatically_derived]impl ::core::clone::Clone for BmpOrSurrogate {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Bmp>;
let _: ::core::clone::AssertParamIsClone<Surrogate>;
*self
}
}Clone, #[automatically_derived]impl ::core::marker::Copy for BmpOrSurrogate { }Copy, #[automatically_derived]impl ::core::hash::Hash for BmpOrSurrogate {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
state);
match self {
Self::Bmp(__self_0) => ::core::hash::Hash::hash(__self_0, state),
Self::Surrogate(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]impl ::core::cmp::Eq for BmpOrSurrogate {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Bmp>;
let _: ::core::cmp::AssertParamIsEq<Surrogate>;
}
}Eq, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
BmpOrSurrogate {
}
#[automatically_derived]impl ::core::cmp::PartialEq for BmpOrSurrogate {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::Bmp(__self_0), Self::Bmp(__arg1_0)) =>
__self_0 == __arg1_0,
(Self::Surrogate(__self_0), Self::Surrogate(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
478pub enum BmpOrSurrogate {
479 Bmp(Bmp),
481 Surrogate(Surrogate),
483}
484
485impl BmpOrSurrogate {
486 #[inline(always)]
488 pub const fn new(code_unit: u16) -> Self {
489 if Bmp::is(code_unit) {
490 Self::Bmp(unsafe { Bmp::new_unchecked(code_unit) })
492 } else {
493 Self::Surrogate(unsafe { Surrogate::new_unchecked(code_unit) })
495 }
496 }
497}
498
499#[cfg(test)]
503mod tests {
504 use super::*;
505
506 #[test]
507 fn test_code_unit_ranges() {
508 for u in 0..=0xFFFFu16 {
509 let surrogate = (0xD800..=0xDFFF).contains(&u);
510 let high = (0xD800..=0xDBFF).contains(&u);
511 let low = (0xDC00..=0xDFFF).contains(&u);
512
513 assert_eq!(Bmp::is(u), !surrogate);
514 assert_eq!(Surrogate::is(u), surrogate);
515 assert_eq!(HighSurrogate::is(u), high);
516 assert_eq!(LowSurrogate::is(u), low);
517
518 assert_eq!(
519 Bmp::try_new(u).map(Bmp::to_u16),
520 Bmp::is(u).then_some(u).ok_or(Utf16CodeUnitError)
521 );
522 assert_eq!(
523 Surrogate::try_new(u).map(Surrogate::to_u16),
524 surrogate.then_some(u).ok_or(Utf16CodeUnitError)
525 );
526 assert_eq!(
527 HighSurrogate::try_new(u).map(HighSurrogate::to_u16),
528 high.then_some(u).ok_or(Utf16CodeUnitError)
529 );
530 assert_eq!(
531 LowSurrogate::try_new(u).map(LowSurrogate::to_u16),
532 low.then_some(u).ok_or(Utf16CodeUnitError)
533 );
534
535 match BmpOrSurrogate::new(u) {
536 BmpOrSurrogate::Bmp(bmp) => {
537 assert!(!surrogate);
538 assert_eq!(bmp.to_u16(), u);
539 assert_eq!(Some(bmp.to_char()), char::from_u32(u as u32));
540 assert_eq!(bmp.as_slice(), &[u]);
541 }
542 BmpOrSurrogate::Surrogate(s) => {
543 assert!(surrogate);
544 assert_eq!(s.to_u16(), u);
545 assert_eq!(
546 HighSurrogate::try_new_with_surrogate(s).map(HighSurrogate::to_u16),
547 high.then_some(u).ok_or(Utf16CodeUnitError)
548 );
549 assert_eq!(
550 LowSurrogate::try_new_with_surrogate(s).map(LowSurrogate::to_u16),
551 low.then_some(u).ok_or(Utf16CodeUnitError)
552 );
553 if let Ok(h) = HighSurrogate::try_new(u) {
554 assert_eq!(h.to_surrogate(), s);
555 }
556 if let Ok(l) = LowSurrogate::try_new(u) {
557 assert_eq!(l.to_surrogate(), s);
558 }
559 }
560 }
561 }
562 }
563
564 #[test]
565 fn test_surrogate_pairs() {
566 let mut previous: Option<(SurrogatePair, char)> = None;
567 for high in 0xD800..=0xDBFFu16 {
568 for low in 0xDC00..=0xDFFFu16 {
569 let pair = SurrogatePair::new(
570 HighSurrogate::try_new(high).unwrap(),
571 LowSurrogate::try_new(low).unwrap(),
572 );
573 let expected = char::decode_utf16([high, low]).next().unwrap().unwrap();
574 let c = pair.to_char();
575 assert_eq!(c, expected);
576 assert_eq!(pair.as_slice(), &[high, low]);
577 let (h, l) = pair.to_typed_code_units();
578 assert_eq!((h.to_u16(), l.to_u16()), (high, low));
579 if let Some((previous_pair, previous_char)) = previous {
580 assert!(previous_pair < pair);
582 assert!(previous_char < c);
583 }
584 previous = Some((pair, c));
585 }
586 }
587 assert_eq!(previous.unwrap().1, char::MAX);
588 }
589
590 #[test]
591 fn test_niche() {
592 assert_ne!(
594 core::mem::size_of::<Option<Bmp>>(),
595 core::mem::size_of::<Bmp>()
596 );
597 assert_eq!(
598 core::mem::size_of::<Option<Surrogate>>(),
599 core::mem::size_of::<Surrogate>()
600 );
601 assert_eq!(
602 core::mem::size_of::<Option<HighSurrogate>>(),
603 core::mem::size_of::<HighSurrogate>()
604 );
605 assert_eq!(
606 core::mem::size_of::<Option<LowSurrogate>>(),
607 core::mem::size_of::<LowSurrogate>()
608 );
609 assert_eq!(
610 core::mem::size_of::<Option<SurrogatePair>>(),
611 core::mem::size_of::<SurrogatePair>()
612 );
613 }
614}