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
use core::convert::{TryFrom, TryInto};
use core::fmt;
pub struct CharConversionError;
#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Char8(u8);
impl TryFrom<char> for Char8 {
type Error = CharConversionError;
fn try_from(value: char) -> Result<Self, Self::Error> {
let code_point = value as u32;
if code_point <= 0xff {
Ok(Char8(code_point as u8))
} else {
Err(CharConversionError)
}
}
}
impl From<Char8> for char {
fn from(char: Char8) -> char {
char.0 as char
}
}
impl From<u8> for Char8 {
fn from(value: u8) -> Self {
Char8(value)
}
}
impl From<Char8> for u8 {
fn from(char: Char8) -> u8 {
char.0
}
}
impl fmt::Debug for Char8 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<char as fmt::Debug>::fmt(&From::from(self.0), f)
}
}
impl fmt::Display for Char8 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<char as fmt::Display>::fmt(&From::from(self.0), f)
}
}
pub const NUL_8: Char8 = Char8(0);
#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Char16(u16);
impl TryFrom<char> for Char16 {
type Error = CharConversionError;
fn try_from(value: char) -> Result<Self, Self::Error> {
let code_point = value as u32;
if code_point <= 0xffff {
Ok(Char16(code_point as u16))
} else {
Err(CharConversionError)
}
}
}
impl From<Char16> for char {
fn from(char: Char16) -> char {
u32::from(char.0).try_into().unwrap()
}
}
impl TryFrom<u16> for Char16 {
type Error = CharConversionError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
let res: Result<char, _> = u32::from(value).try_into();
if let Ok(ch) = res {
ch.try_into()
} else {
Err(CharConversionError)
}
}
}
impl From<Char16> for u16 {
fn from(char: Char16) -> u16 {
char.0 as u16
}
}
impl fmt::Debug for Char16 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Ok(c) = u32::from(self.0).try_into() {
<char as fmt::Debug>::fmt(&c, f)
} else {
write!(f, "Char16({:?})", self.0)
}
}
}
impl fmt::Display for Char16 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Ok(c) = u32::from(self.0).try_into() {
<char as fmt::Display>::fmt(&c, f)
} else {
write!(f, "{}", core::char::REPLACEMENT_CHARACTER)
}
}
}
pub const NUL_16: Char16 = Char16(0);