1use crate::pool::{ GlobalPool, Pool, SlicesWrap };
2use ::std::ops::{ Add, AddAssign, Bound, Deref, RangeBounds };
3use ::std::string::{ self as std_string, String as StdString };
4use ::std::str as std_str;
5
6pub struct String<P: Pool = GlobalPool> {
7 raw: P::Raw,
8 pool: P
9}
10
11#[cfg(test)]
12#[path = "./tests/string.rs"]
13mod tests;
14
15impl String {
17 pub fn new() -> Self {
18 Self::new_in(GlobalPool)
19 }
20
21 pub fn from_utf8(vec: Vec<u8>) -> Result<Self, std_string::FromUtf8Error> {
22 Self::from_utf8_in(vec, GlobalPool)
23 }
24
25 pub fn from_utf8_slice(slice: &[u8]) -> Result<Self, std_str::Utf8Error> {
26 Self::from_utf8_slice_in(slice, GlobalPool)
27 }
28
29 pub fn from_utf8_lossy(v: &[u8]) -> Self {
30 Self::from_utf8_lossy_in(v, GlobalPool)
31 }
32
33 pub fn from_utf16(v: &[u16]) -> Result<Self, std_string::FromUtf16Error> {
34 Self::from_utf16_in(v, GlobalPool)
35 }
36
37 pub fn from_utf16_lossy(v: &[u16]) -> Self {
38 Self::from_utf16_lossy_in(v, GlobalPool)
39 }
40
41 pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> Self {
49 Self::from_utf8_unchecked_in(bytes, GlobalPool)
50 }
51
52 pub unsafe fn from_utf8_unchecked_slice(slice: &[u8]) -> Self {
53 Self::from_utf8_unchecked_slice_in(slice, GlobalPool)
54 }
55}
56
57impl<P: Pool> String<P> {
59 pub fn new_in(pool: P) -> Self {
60 let raw = pool.raw_empty();
61 Self { raw, pool }
62 }
63
64 pub fn from_utf8_in(vec: Vec<u8>, pool: P) -> Result<Self, std_string::FromUtf8Error> {
65 let std_string = StdString::from_utf8(vec)?;
69 let vec = std_string.into_bytes();
70 let raw = unsafe { pool.raw_from_vec(vec) };
71 Ok(Self { raw, pool })
72 }
73
74 pub fn from_utf8_slice_in(slice: &[u8], pool: P) -> Result<Self, std_str::Utf8Error> {
75 let s = std_str::from_utf8(slice)?;
76 let raw = unsafe { pool.raw_from_slice(s.as_bytes()) };
77 Ok(Self { raw, pool })
78 }
79
80 pub fn from_utf8_lossy_in(v: &[u8], pool: P) -> Self {
81 let s = StdString::from_utf8_lossy(v);
82 let raw = unsafe { pool.raw_from_slice(s.as_bytes()) };
83 Self { raw, pool }
84 }
85
86 pub fn from_utf16_in(v: &[u16], pool: P) -> Result<Self, std_string::FromUtf16Error> {
87 let s = StdString::from_utf16(v)?;
88 let raw = unsafe { pool.raw_from_slice(s.as_bytes()) };
89 Ok(Self { raw, pool })
90 }
91
92 pub fn from_utf16_lossy_in(v: &[u16], pool: P) -> Self {
93 let s = StdString::from_utf16_lossy(v);
94 let raw = unsafe { pool.raw_from_slice(s.as_bytes()) };
95 Self { raw, pool }
96 }
97
98 pub unsafe fn from_utf8_unchecked_in(bytes: Vec<u8>, pool: P) -> Self {
99 let raw = pool.raw_from_vec(bytes);
100 Self { raw, pool }
101 }
102
103 pub unsafe fn from_utf8_unchecked_slice_in(slice: &[u8], pool: P) -> Self {
104 let raw = pool.raw_from_slice(slice);
105 Self { raw, pool }
106 }
107
108 pub fn to_other_pool<P2: Pool>(&self, pool: P2) -> String<P2> {
109 let slice = self.pool.raw_to_slice(&self.raw);
110 let raw = unsafe { pool.raw_from_slice(slice) };
111 String { raw, pool }
112 }
113
114 pub fn into_other_pool<P2: Pool>(self, pool: P2) -> String<P2> {
115 let vec = self.pool.raw_into_vec(self.raw);
116 let raw = unsafe { pool.raw_from_vec(vec) };
117 String { raw, pool }
118 }
119
120 pub fn clone_to<P2: Pool>(&self, pool: P2) -> String<P2> {
121 self.to_other_pool(pool)
122 }
123}
124
125impl<P: Pool> String<P> {
127 pub fn into_bytes(self) -> Vec<u8> {
128 self.pool.raw_into_vec(self.raw)
129 }
130
131 pub fn as_str(&self) -> &str {
132 unsafe { std_str::from_utf8_unchecked(self.as_bytes()) }
133 }
134
135 pub fn push_str(&mut self, string: &str) {
138 let new_raw = unsafe {
139 self.pool.raw_from_slices(SlicesWrap(&[
140 self.as_bytes(),
141 string.as_bytes()
142 ]))
143 };
144
145 self.raw = new_raw;
146 }
147
148 pub fn push(&mut self, ch: char) {
158 self.push_str(ch.encode_utf8(&mut [0u8; 4]));
159 }
160
161 pub fn as_bytes(&self) -> &[u8] {
162 self.pool.raw_to_slice(&self.raw)
163 }
164
165 pub fn truncate(&mut self, new_len: usize) {
166 if new_len > self.len() { return }
167
168 assert!(self.is_char_boundary(new_len));
169 let new_slice = &self.as_bytes()[..new_len];
170 let new_raw = unsafe { self.pool.raw_from_slice(new_slice) };
171
172 self.raw = new_raw;
173 }
174
175 pub fn pop(&mut self) -> Option<char> {
176 let ch = self.chars().next_back()?;
177 let new_len = self.len() - ch.len_utf8();
178
179 let new_slice = &self.as_bytes()[..new_len];
180 let new_raw = unsafe { self.pool.raw_from_slice(new_slice) };
181
182 self.raw = new_raw;
183 Some(ch)
184 }
185
186 pub fn remove(&mut self, i: usize) -> char {
187 let ch = self[i..].chars().next()
189 .expect("cannot remove a char from the end of a string");
190 let next = i + ch.len_utf8();
191
192 let slice = self.as_bytes();
193 let new_raw = unsafe {
194 self.pool.raw_from_slices(SlicesWrap(&[
195 &slice[..i],
196 &slice[next..]
197 ]))
198 };
199
200 self.raw = new_raw;
201 ch
202 }
203
204 pub fn retain<F>(&mut self, mut f: F)
207 where
208 F: FnMut(char) -> bool
209 {
210 let mut retained = Vec::with_capacity((self.len() / 2) + 1);
218 let mut state = None;
219
220 for (i, char) in self.char_indices() {
221 match (f(char), state) {
222 (true, None) => {
224 state = Some(i);
225 }
226
227 (false, Some(i_start)) => {
229 retained.push(self[i_start..i].as_bytes());
230 state = None;
231 }
232
233 (true, Some(_)) => { }
235
236 (false, None) => { }
238 }
239 }
240
241 if let Some(i_start) = state {
242 retained.push(self[i_start..].as_bytes());
243 }
244
245 let new_raw = unsafe { self.pool.raw_from_slices(SlicesWrap(&retained)) };
246 self.raw = new_raw;
247 }
248
249 pub fn insert(&mut self, i: usize, ch: char) {
250 self.insert_str(i, ch.encode_utf8(&mut [0u8; 4]));
251 }
252
253 pub fn insert_str(&mut self, i: usize, string: &str) {
254 assert!(self.is_char_boundary(i));
255 let slice = self.as_bytes();
256
257 let new_raw = unsafe {
258 self.pool.raw_from_slices(SlicesWrap(&[
259 &slice[..i],
260 string.as_bytes(),
261 &slice[i..]
262 ]))
263 };
264
265 self.raw = new_raw;
266 }
267
268 pub fn split_off(&mut self, at: usize) -> Self {
271 self.split_off_in(at, self.pool.clone())
272 }
273
274 pub fn split_off_in<P2: Pool>(&mut self, at: usize, pool: P2) -> String<P2> {
275 assert!(self.is_char_boundary(at));
276
277 let self_raw = unsafe { self.pool.raw_from_slice(self[..at].as_bytes()) };
278 let other_raw = unsafe { pool.raw_from_slice(self[at..].as_bytes()) };
279
280 self.raw = self_raw;
281 String { raw: other_raw, pool }
282 }
283
284 pub fn clear(&mut self) {
285 self.raw = self.pool.raw_empty();
286 }
287
288 pub fn into_boxed_str(self) -> Box<str> {
292 let boxed = self.pool.raw_into_boxed_slice(self.raw);
293 unsafe { std_str::from_boxed_utf8_unchecked(boxed) }
294 }
295
296 pub fn leak<'h>(self) -> &'h mut str {
297 let slice = self.pool.raw_into_vec(self.raw).leak();
298 unsafe { std_str::from_utf8_unchecked_mut(slice) }
299 }
300}
301
302impl<P: Pool> Add<&str> for String<P> {
303 type Output = Self;
304 fn add(mut self, rhs: &str) -> Self {
305 self += rhs;
307 self
308 }
309}
310
311impl<P: Pool> Add<&str> for &String<P> {
312 type Output = String<P>;
313 fn add(self, rhs: &str) -> String<P> {
314 let raw = unsafe {
315 self.pool.raw_from_slices(SlicesWrap(&[
316 self.as_bytes(),
317 rhs.as_bytes()
318 ]))
319 };
320 let pool = self.pool.clone();
321
322 String { raw, pool }
323 }
324}
325
326impl<P: Pool, P2: Pool> Add<String<P2>> for String<P> {
327 type Output = Self;
328 fn add(self, rhs: String<P2>) -> Self {
329 self + &*rhs
331 }
332}
333
334impl<P: Pool, P2: Pool> Add<String<P2>> for &String<P> {
335 type Output = String<P>;
336 fn add(self, rhs: String<P2>) -> String<P> {
337 self + &*rhs
339 }
340}
341
342impl<P: Pool, P2: Pool> Add<&String<P2>> for String<P> {
343 type Output = Self;
344 fn add(self, rhs: &String<P2>) -> Self {
345 self + &**rhs
347 }
348}
349
350impl<P: Pool, P2: Pool> Add<&String<P2>> for &String<P> {
351 type Output = String<P>;
352 fn add(self, rhs: &String<P2>) -> String<P> {
353 self + &**rhs
355 }
356}
357
358
359impl<P: Pool> AddAssign<&str> for String<P> {
360 fn add_assign(&mut self, rhs: &str) {
361 self.push_str(rhs);
362 }
363}
364
365impl<P: Pool, P2: Pool> AddAssign<String<P2>> for String<P> {
366 fn add_assign(&mut self, rhs: String<P2>) {
367 *self += &*rhs
369 }
370}
371
372impl<P: Pool, P2: Pool> AddAssign<&String<P2>> for String<P> {
373 fn add_assign(&mut self, rhs: &String<P2>) {
374 *self += &**rhs
376 }
377}
378
379impl<P: Pool> Clone for String<P> {
380 fn clone(&self) -> Self {
381 let raw = self.pool.raw_clone(&self.raw);
382 let pool = self.pool.clone();
383 Self { raw, pool }
384 }
385}
386
387impl<P: Pool> Deref for String<P> {
388 type Target = str;
389 fn deref(&self) -> &str {
390 self.as_str()
391 }
392}
393
394impl From<&str> for String {
395 fn from(s: &str) -> Self {
396 Self::from((s, GlobalPool))
397 }
398}
399
400impl<P: Pool> From<(&str, P)> for String<P> {
401 fn from((s, pool): (&str, P)) -> Self {
402 let raw = unsafe { pool.raw_from_slice(s.as_bytes()) };
403 Self { raw, pool }
404 }
405}