obeli_sk_boa_string/
code_point.rs1use std::fmt::Write;
2
3#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum CodePoint {
9 Unicode(char),
11
12 UnpairedSurrogate(u16),
14}
15
16impl CodePoint {
17 #[inline]
19 #[must_use]
20 pub const fn code_unit_count(self) -> usize {
21 match self {
22 Self::Unicode(c) => c.len_utf16(),
23 Self::UnpairedSurrogate(_) => 1,
24 }
25 }
26
27 #[inline]
29 #[must_use]
30 pub fn as_u32(self) -> u32 {
31 match self {
32 Self::Unicode(c) => u32::from(c),
33 Self::UnpairedSurrogate(surr) => u32::from(surr),
34 }
35 }
36
37 #[inline]
40 #[must_use]
41 pub const fn as_char(self) -> Option<char> {
42 match self {
43 Self::Unicode(c) => Some(c),
44 Self::UnpairedSurrogate(_) => None,
45 }
46 }
47
48 #[inline]
56 #[must_use]
57 pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
58 match self {
59 Self::Unicode(c) => c.encode_utf16(dst),
60 Self::UnpairedSurrogate(surr) => {
61 dst[0] = surr;
62 &mut dst[0..=0]
63 }
64 }
65 }
66}
67
68impl std::fmt::Display for CodePoint {
69 #[inline]
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 match self {
72 CodePoint::Unicode(c) => f.write_char(*c),
73 CodePoint::UnpairedSurrogate(c) => {
74 write!(f, "\\u{c:04X}")
75 }
76 }
77 }
78}
79
80impl From<char> for CodePoint {
81 fn from(value: char) -> Self {
82 Self::Unicode(value)
83 }
84}
85
86impl From<u16> for CodePoint {
87 fn from(value: u16) -> Self {
88 char::from_u32(u32::from(value))
89 .map_or_else(|| CodePoint::UnpairedSurrogate(value), CodePoint::Unicode)
90 }
91}