string_alloc/
string.rs

1use alloc::vec::Vec;
2use core::borrow::Borrow;
3use core::fmt;
4use core::hash::{Hash, Hasher};
5use core::ops::Deref;
6use core::str;
7
8use ::alloc::alloc::{Allocator, Global};
9
10#[derive(Debug, Clone)]
11pub struct String<A: Allocator + Clone + Default = Global> {
12    vec: Vec<u8, A>,
13}
14
15impl<A: Allocator + Clone + Default> String<A> {
16    pub fn new_in(alloc: A) -> Self {
17        Self {
18            vec: Vec::new_in(alloc),
19        }
20    }
21
22    pub fn with_capacity_in(cap: usize, alloc: A) -> Self {
23        Self {
24            vec: Vec::with_capacity_in(cap, alloc),
25        }
26    }
27
28    pub fn from_str_in(s: &str, alloc: A) -> Self {
29        let mut vec = Vec::with_capacity_in(s.len(), alloc);
30        vec.extend_from_slice(s.as_bytes());
31        Self { vec }
32    }
33
34    pub fn from_utf8_in(vec: Vec<u8, A>) -> Result<Self, core::str::Utf8Error> {
35        match str::from_utf8(&vec) {
36            Ok(_) => Ok(Self { vec }),
37            Err(e) => Err(e),
38        }
39    }
40
41    pub unsafe fn from_utf8_unchecked_in(vec: Vec<u8, A>) -> Self {
42        Self { vec }
43    }
44
45    pub fn push_str(&mut self, s: &str) {
46        self.vec.extend_from_slice(s.as_bytes());
47    }
48
49    pub fn push(&mut self, ch: char) {
50        let mut buf = [0; 4];
51        self.push_str(ch.encode_utf8(&mut buf));
52    }
53
54    pub fn pop(&mut self) -> Option<char> {
55        let s = self.deref();
56        let ch = s.chars().rev().next()?;
57        let new_len = s.len() - ch.len_utf8();
58        self.vec.truncate(new_len);
59        Some(ch)
60    }
61
62    pub fn insert(&mut self, idx: usize, ch: char) {
63        let mut buf = [0; 4];
64        let bytes = ch.encode_utf8(&mut buf);
65        let byte_idx = {
66            let s = self.deref();
67            s.char_indices()
68                .nth(idx)
69                .map(|(i, _)| i)
70                .unwrap_or_else(|| panic!("insertion index (is {}) should be <= len (is {})", idx, s.len()))
71        };
72        self.vec.splice(byte_idx..byte_idx, bytes.as_bytes().iter().cloned());
73    }
74
75    pub fn remove(&mut self, idx: usize) -> char {
76        let (start, ch) = {
77            let s = self.deref();
78            s.char_indices()
79                .nth(idx)
80                .unwrap_or_else(|| panic!("removal index (is {}) should be < len (is {})", idx, s.chars().count()))
81        };
82        let end = start + ch.len_utf8();
83        self.vec.drain(start..end);
84        ch
85    }
86
87    pub fn split_off(&mut self, at: usize) -> Self
88    where
89        A: Clone,
90    {
91        let byte_idx = {
92            let s = self.deref();
93            s.char_indices().nth(at).map(|(i, _)| i).unwrap_or_else(|| {
94                panic!(
95                    "split_off index (is {}) should be <= len (is {})",
96                    at,
97                    s.chars().count()
98                )
99            })
100        };
101        let vec = self.vec.split_off(byte_idx);
102        Self { vec }
103    }
104
105    pub fn retain<F>(&mut self, mut f: F)
106    where
107        F: FnMut(char) -> bool,
108    {
109        let mut i = 0;
110        let mut len = self.len();
111        while i < len {
112            let ch = {
113                let s = self.deref();
114                match s[i..].chars().next() {
115                    Some(c) => c,
116                    None => break,
117                }
118            };
119            let ch_len = ch.len_utf8();
120            if !f(ch) {
121                self.vec.drain(i..i + ch_len);
122                len -= ch_len;
123            } else {
124                i += ch_len;
125            }
126        }
127    }
128
129    pub fn reserve(&mut self, additional: usize) {
130        self.vec.reserve(additional);
131    }
132
133    pub fn reserve_exact(&mut self, additional: usize) {
134        self.vec.reserve_exact(additional);
135    }
136
137    pub fn shrink_to_fit(&mut self) {
138        self.vec.shrink_to_fit();
139    }
140
141    pub fn clear(&mut self) {
142        self.vec.clear();
143    }
144
145    pub fn truncate(&mut self, new_len: usize) {
146        let current_len = self.chars().count();
147        if new_len > current_len {
148            panic!("truncate index (is {}) should be <= len (is {})", new_len, current_len);
149        }
150        let byte_idx = self.char_indices().nth(new_len).map(|(i, _)| i).unwrap_or(self.len());
151        self.vec.truncate(byte_idx);
152    }
153
154    pub fn len(&self) -> usize {
155        self.vec.len()
156    }
157
158    pub fn capacity(&self) -> usize {
159        self.vec.capacity()
160    }
161}
162
163impl<A: Allocator + Clone + Default> Deref for String<A> {
164    type Target = str;
165    fn deref(&self) -> &Self::Target {
166        unsafe { str::from_utf8_unchecked(&self.vec) }
167    }
168}
169
170impl<A: Allocator + Clone + Default> fmt::Display for String<A> {
171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172        write!(f, "{}", self.deref())
173    }
174}
175
176impl<A: Allocator + Clone + Default> PartialEq<str> for String<A> {
177    fn eq(&self, other: &str) -> bool {
178        self.deref() == other
179    }
180}
181
182impl<A: Allocator + Clone + Default> PartialEq for String<A> {
183    fn eq(&self, other: &Self) -> bool {
184        self.deref() == other.deref()
185    }
186}
187
188impl<A: Allocator + Clone + Default> Eq for String<A> {}
189
190impl<A: Allocator + Clone + Default> PartialOrd for String<A> {
191    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
192        self.deref().partial_cmp(other.deref())
193    }
194}
195
196impl<A: Allocator + Clone + Default> Ord for String<A> {
197    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
198        self.deref().cmp(other.deref())
199    }
200}
201
202impl<A: Allocator + Clone + Default> Hash for String<A> {
203    fn hash<H: Hasher>(&self, state: &mut H) {
204        self.deref().hash(state);
205    }
206}
207
208impl<A: Allocator + Clone + Default> AsRef<str> for String<A> {
209    fn as_ref(&self) -> &str {
210        self.deref()
211    }
212}
213
214impl<A: Allocator + Clone + Default> AsRef<[u8]> for String<A> {
215    fn as_ref(&self) -> &[u8] {
216        self.vec.as_ref()
217    }
218}
219
220impl<A: Allocator + Clone + Default> Borrow<str> for String<A> {
221    fn borrow(&self) -> &str {
222        self.deref()
223    }
224}
225
226impl<A: Allocator + Clone + Default> From<&str> for String<A> {
227    fn from(s: &str) -> Self {
228        Self::from_str_in(s, A::default())
229    }
230}
231
232impl<A: Allocator + Clone + Default> From<Vec<u8, A>> for String<A> {
233    fn from(vec: Vec<u8, A>) -> Self {
234        Self { vec }
235    }
236}
237
238impl<A: Allocator + Clone + Default> Into<Vec<u8, A>> for String<A> {
239    fn into(self) -> Vec<u8, A> {
240        self.vec
241    }
242}