1use super::*;
2
3pub type Result<T> = ::core::result::Result<T, Error>;
4
5#[repr(u8)]
6#[derive(Debug)]
7#[derive(Clone)]
8#[derive(PartialEq)]
9#[derive(Eq)]
10#[derive(PartialOrd)]
11#[derive(Ord)]
12#[derive(Hash)]
13#[derive(::strum_macros::EnumCount)]
14#[derive(::strum_macros::EnumIs)]
15#[derive(::thiserror::Error)]
16#[derive(::serde::Serialize)]
17#[derive(::serde::Deserialize)]
18pub enum Error {
19 #[error("Overflow.")]
20 Overflow,
21 #[error("Invalid sequence.")]
22 InvalidSequence,
23 #[error("Empty.")]
24 Empty
25}
26
27#[derive(Clone)]
28#[derive(Hash)]
29#[derive(::serde::Serialize)]
30#[derive(::serde::Deserialize)]
31pub struct Utf8<const A: usize> {
32 buf: array::Array<A, u8>,
33 len: usize
34}
35
36impl<const A: usize> Utf8<A> {
37 #[inline]
38 pub const fn new() -> Self {
39 Self {
40 buf: array::Array {
41 buf: unsafe {
42 core::mem::MaybeUninit::uninit().assume_init()
43 },
44 len: 0
45 },
46 len: 0
47 }
48 }
49
50 #[inline]
51 pub const fn encode<B>(bytes: &[u8]) -> Self {
52 let mut ret: Self = Self::new();
53 let mut key: usize = 0;
54 while key < bytes.len() && ret.buf.len < A {
55 let byte = bytes[key];
56 ret.buf.buf[key].write(byte);
57 ret.buf.len += 1;
58 if byte & 0b1100_0000 != 0b1000_0000 {
59 ret.len += 1
60 }
61 key += 1;
62 }
63 ret
64 }
65
66 #[inline]
67 pub fn push_str(&mut self, s: &str) -> Result<()> {
68 let old_buf_len: usize = self.buf.len();
69 let old_len: usize = self.len;
70 for c in s.chars() {
71 if let Err(e) = self.push(c) {
72 self.buf.len = old_buf_len;
73 self.len = old_len;
74 return Err(e)
75 }
76 }
77 Ok(())
78 }
79
80 #[inline]
81 pub const fn push(&mut self, c: char) -> Result<()> {
82 let code: u32 = c as u32;
83 let arr: &mut array::Array<A, u8> = &mut self.buf;
84 let req: usize = if code <= 0x7f {
85 1
86 } else if code <= 0x7ff {
87 2
88 } else if code <= 0xffff {
89 3
90 } else {
91 4
92 };
93 if arr.len() + req > A {
94 return Err(Error::Overflow)
95 }
96 match req {
97 1 => {
98 let _ = arr.push(code as u8);
99 },
100 2 => {
101 let _ = arr.push((0b1100_0000 | ((code >> 6) & 0x1F)) as u8);
102 let _ = arr.push((0b1000_0000 | (code & 0x3F)) as u8);
103 },
104 3 => {
105 let _ = arr.push((0b1110_0000 | ((code >> 12) & 0x0F)) as u8);
106 let _ = arr.push((0b1000_0000 | ((code >> 6) & 0x3F)) as u8);
107 let _ = arr.push((0b1000_0000 | (code & 0x3F)) as u8);
108 },
109 4 => {
110 let _ = arr.push((0b1111_0000 | ((code >> 18) & 0x07)) as u8);
111 let _ = arr.push((0b1000_0000 | ((code >> 12) & 0x3F)) as u8);
112 let _ = arr.push((0b1000_0000 | ((code >> 6) & 0x3F)) as u8);
113 let _ = arr.push((0b1000_0000 | (code & 0x3F)) as u8);
114 },
115 _ => unreachable!()
116 }
117 self.len += 1;
118 Ok(())
119 }
120
121 #[inline]
122 pub const fn pop(&mut self) -> Result<()> {
123 let buf: &[u8] = self.buf.as_slice();
124 let key: usize = self.buf.len();
125 if key == 0 {
126 return Err(Error::Empty)
127 }
128 let mut back: usize = 1;
129 while back <= 4 {
130 if key < back {
131 break
132 }
133 let b: u8 = buf[key - back];
134 if back == 1 && b & 0b1000_0000 == 0 {
135 self.buf.len -= 1;
136 self.len -= 1;
137 return Ok(())
138 } else if back == 2 && b & 0b1110_0000 == 0b1100_0000 {
139 self.buf.len -= 2;
140 self.len -= 1;
141 return Ok(())
142 } else if back == 3 && b & 0b1111_0000 == 0b1110_0000 {
143 self.buf.len -= 3;
144 self.len -= 1;
145 return Ok(())
146 } else if back == 4 && b & 0b1111_1000 == 0b1111_0000 {
147 self.buf.len -= 4;
148 self.len -= 1;
149 return Ok(())
150 }
151 back += 1;
152 }
153 Err(Error::InvalidSequence)
154 }
155
156 pub fn cast<const B: usize>(self) -> Result<Utf8<B>> {
157 let a: Utf8<A> = self;
158 let a: &str = a.as_str();
159 let mut b: Utf8<B> = Utf8::new();
160 b.push_str(a)?;
161 Ok(b)
162 }
163
164 pub fn as_str(&self) -> &str {
165 let ret = self.buf.as_slice();
166 ::core::str::from_utf8(ret)
167 .ok()
168 .ok_or(Error::InvalidSequence)
169 .unwrap()
170 }
171}
172
173impl<const T: usize> Default for Utf8<T> {
174 fn default() -> Self {
175 Self::new()
176 }
177}
178
179impl<const T: usize> TryFrom<&str> for Utf8<T> {
180 type Error = Error;
181
182 fn try_from(value: &str) -> ::core::result::Result<Self, Self::Error> {
183 let mut s: Self = Self::new();
184 s.push_str(value)?;
185 Ok(s)
186 }
187}
188
189#[cfg(feature = "std")]
190impl<const T: usize> TryFrom<String> for Utf8<T> {
191 type Error = Error;
192
193 fn try_from(value: String) -> ::core::result::Result<Self, Self::Error> {
194 let value: &str = &value;
195 let mut s: Self = Self::new();
196 s.push_str(value)?;
197 Ok(s)
198 }
199}
200
201impl<const T: usize> Eq for Utf8<T> {}
202impl<const T: usize> PartialEq for Utf8<T> {
203 fn eq(&self, other: &Self) -> bool {
204 self.len == other.len && self.buf == other.buf
205 }
206}
207
208impl<const T: usize> Ord for Utf8<T> {
209 fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
210 let x: &str = self.as_str();
211 let y: &str = other.as_str();
212 x.cmp(y)
213 }
214}
215
216#[allow(clippy::non_canonical_partial_ord_impl)]
217impl<const T: usize> PartialOrd for Utf8<T> {
218 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
219 let x: &str = self.as_str();
220 let y: &str = other.as_str();
221 let ret: ::core::cmp::Ordering = x.cmp(y);
222 Some(ret)
223 }
224}
225
226impl<const T: usize> ::core::fmt::Debug for Utf8<T> {
227 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
228 f
229 .debug_struct("Utf8")
230 .field("len", &self.len)
231 .field("buf_len", &self.buf.len)
232 .field("as_str", &self.as_str())
233 .finish()
234 }
235}
236
237impl<const T: usize> ::core::fmt::Display for Utf8<T> {
238 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
239 let s: &str = self.as_str();
240 write!(f, "{}", s)
241 }
242}
243
244#[test]
245fn test() {
246 let s: Utf8<32> = "Hello World".try_into().unwrap();
247 let s_ok: Utf8<32> = "Hello World".try_into().unwrap();
248 assert_eq!(s, s_ok);
249}
250