1pub struct String<A: Allocator = GlobalAllocator> {
3 buffer: Array<u8, A>,
4}
5
6impl<A: Allocator> String<A> {
7 pub fn new_with(alloc: A) -> Self {
18 Self {
19 buffer: Array::new_with(alloc),
20 }
21 }
22
23 pub fn from_str_with(s: &str, alloc: A) -> Self {
36 let slice = s.as_bytes();
37 let mut buf = Array::new_with(alloc);
38 buf.resize(slice.len(), 0);
39
40 unsafe {
41 ptr::copy_nonoverlapping(s.as_ptr(), buf.as_mut_ptr(), slice.len());
42 }
43
44 return Self { buffer: buf };
45 }
46
47 #[inline]
49 pub fn as_str(&self) -> &str {
50 self
51 }
52
53 pub fn push(&mut self, c: char) {
55 let mut bytes = [0u8; 4];
56 c.encode_utf8(&mut bytes);
57 self.buffer.extend(bytes[0..c.len_utf8()].iter());
58 }
59}
60
61impl<A: Allocator> TryFrom<Array<u8, A>> for String<A> {
62 type Error = core::str::Utf8Error;
63
64 fn try_from(array: Array<u8, A>) -> Result<Self, Self::Error> {
65 str::from_utf8(&array)?;
66 Ok(Self { buffer: array })
67 }
68}
69
70impl String<GlobalAllocator> {
71 pub fn new() -> Self {
83 Self::new_with(GlobalAllocator)
84 }
85
86 pub fn from(s: &str) -> Self {
98 Self::from_str_with(s, GlobalAllocator)
99 }
100}
101
102impl<A: Allocator> AsRef<str> for String<A> {
103 #[inline]
105 fn as_ref(&self) -> &str {
106 self
107 }
108}
109
110impl<A: Allocator> Borrow<str> for String<A> {
111 #[inline]
113 fn borrow(&self) -> &str {
114 self
115 }
116}
117
118impl<A: Allocator> Deref for String<A> {
119 type Target = str;
120
121 #[inline]
134 fn deref(&self) -> &Self::Target {
135 unsafe { str::from_utf8_unchecked(&self.buffer) }
136 }
137}
138
139unsafe impl Send for String<GlobalAllocator> {}
140unsafe impl Sync for String<GlobalAllocator> {}
141
142impl<A: Allocator> DerefMut for String<A> {
143 #[inline]
145 fn deref_mut(&mut self) -> &mut str {
146 unsafe { str::from_utf8_unchecked_mut(&mut self.buffer) }
147 }
148}
149
150impl<A: Allocator> fmt::Display for String<A> {
151 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 fmt::Display::fmt(self.as_str(), f)
154 }
155}
156
157impl<A: Allocator> fmt::Debug for String<A> {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 fmt::Display::fmt(self.as_str(), f)
160 }
161}
162
163impl<A, T> PartialEq<T> for String<A>
164where
165 A: Allocator,
166 T: AsRef<str>,
167{
168 #[inline]
169 fn eq(&self, other: &T) -> bool {
170 PartialEq::eq(self.as_str(), other.as_ref())
171 }
172}
173
174impl<A: Allocator> Eq for String<A> {}
175
176impl<A: Allocator> Hash for String<A> {
177 fn hash<H: Hasher>(&self, h: &mut H) {
178 Hash::hash(self.as_str(), h);
179 }
180}
181
182pub struct StringWide<A: Allocator = GlobalAllocator> {
187 buf: Array<u16, A>,
188}
189
190impl<A: Allocator> StringWide<A> {
191 pub fn new_with(alloc: A) -> Self {
203 Self {
204 buf: Array::new_with(alloc),
205 }
206 }
207
208 pub fn from_str_with(s: &str, alloc: A) -> Self {
221 let w_iter = s.encode_utf16();
222
223 let mut buf = Array::new_with(alloc);
224 buf.reserve(w_iter.size_hint().0);
225
226 for wchar in w_iter {
227 buf.push(wchar);
228 }
229
230 Self { buf }
231 }
232
233 #[inline]
235 pub fn push(&mut self, c: char) {
236 let len = c.len_utf16();
237 self.buf.resize(self.buf.len() + len, 0);
238
239 let start = self.buf.len() - len;
240 c.encode_utf16(&mut self.buf[start..]);
241 }
242}
243
244impl StringWide<GlobalAllocator> {
245 pub fn new() -> Self {
256 Self::new_with(GlobalAllocator)
257 }
258
259 pub fn from(s: &str) -> Self {
271 Self::from_str_with(s, GlobalAllocator)
272 }
273}
274
275impl<A: Allocator> AsRef<[u16]> for StringWide<A> {
276 #[inline]
277 fn as_ref(&self) -> &[u16] {
278 &self.buf
279 }
280}
281
282impl<A: Allocator> Deref for StringWide<A> {
283 type Target = [u16];
284
285 #[inline]
286 fn deref(&self) -> &[u16] {
287 &self.buf
288 }
289}
290
291impl<A: Allocator> DerefMut for StringWide<A> {
292 #[inline]
293 fn deref_mut(&mut self) -> &mut [u16] {
294 &mut self.buf
295 }
296}
297
298unsafe impl Send for StringWide<GlobalAllocator> {}
299unsafe impl Sync for StringWide<GlobalAllocator> {}
300
301use {
304 crate::{
305 alloc::{Allocator, GlobalAllocator},
306 array::Array,
307 },
308 core::{
309 borrow::Borrow,
310 cmp::{Eq, PartialEq},
311 fmt,
312 hash::{Hash, Hasher},
313 ops::{Deref, DerefMut},
314 ptr, str,
315 },
316};