1use crate::auxiliary::zero;
4use crate::guard;
5use crate::vec::{InnerVec, Vec};
6
7use std::cmp::{PartialEq, min, max};
8use std::convert::From;
9use std::iter::FromIterator;
10use std::mem::MaybeUninit;
11use std::str::Chars;
12
13use unicode_normalization::UnicodeNormalization;
14use unicode_normalization::char::decompose_canonical;
15
16#[must_use]
18#[derive(Debug, Default)]
19pub struct String(Vec<u8>);
20
21#[must_use]
23#[derive(Debug)]
24pub struct Ref<'t>(guard::Ref<'t, InnerVec<u8>>);
25
26#[must_use]
28#[derive(Debug)]
29pub struct RefMut<'t>(guard::RefMut<'t, InnerVec<u8>>);
30
31impl String {
32 const CMP_MIN: usize = 32;
33
34 fn eq_slice(a: &InnerVec<u8>, b: &[u8]) -> bool {
35 if a.capacity() == 0 {
36 debug_assert!(a.is_empty());
37 b.is_empty()
38 } else {
39 debug_assert!(a.capacity() >= Self::CMP_MIN);
40
41 b.iter().take(a.capacity()).enumerate().fold(0, |d, (i, e)| {
42 d | unsafe { a.as_ptr().add(i).read() as usize ^ *e as usize }
43 }) | (max(a.len(), b.len()) - min(a.len(), b.len())) == 0
44 }
45 }
46
47 #[inline]
48 pub fn new() -> Self {
49 Self(Vec::new())
50 }
51
52 #[inline]
53 pub fn with_capacity(capacity: usize) -> Self {
54 Self(Vec::with_capacity(capacity))
55 }
56
57 #[inline]
58 pub fn capacity(&self) -> usize {
59 self.0.capacity()
60 }
61
62 #[inline]
63 pub fn len(&self) -> usize {
64 self.0.len()
65 }
66
67 #[inline]
68 pub fn is_empty(&self) -> bool {
69 self.0.is_empty()
70 }
71
72 #[inline]
73 pub fn reserve(&mut self, capacity: usize) {
74 self.0.reserve(capacity);
75 }
76
77 #[inline]
78 pub fn reserve_exact(&mut self, capacity: usize) {
79 self.0.reserve_exact(capacity);
80 }
81
82 #[inline]
83 pub fn borrow(&self) -> Ref<'_> {
84 Ref(self.0.borrow())
85 }
86
87 #[inline]
88 pub fn borrow_mut(&mut self) -> RefMut<'_> {
89 RefMut(self.0.borrow_mut())
90 }
91}
92
93impl FromIterator<char> for String {
94 fn from_iter<I>(into: I) -> Self
95 where I: IntoIterator<Item = char> {
96 let iter = into.into_iter();
97 let (lower, upper) = iter.size_hint();
98 let mut string = Self::with_capacity(upper.unwrap_or(lower));
99
100 {
101 let mut mutable = string.borrow_mut();
102
103 for ch in iter {
104 mutable.push(ch);
105 }
106 }
107
108 string
109 }
110}
111
112impl From<&str> for String {
113 fn from(source: &str) -> Self {
114 let iter = source.nfd();
115 let (lower, upper) = iter.size_hint();
116 let mut string = Self::with_capacity(upper.unwrap_or(lower));
117
118 {
119 let mut mutable = string.borrow_mut();
120
121 for decomp in iter {
122 mutable.reserve(decomp.len_utf8());
123 decomp.encode_utf8(unsafe { MaybeUninit::slice_assume_init_mut(mutable.0.spare_capacity_mut()) });
124 unsafe { mutable.0.set_len(mutable.0.len() + decomp.len_utf8()); }
125 }
126 }
127
128 string
129 }
130}
131
132impl From<std::string::String> for String {
133 fn from(mut source: std::string::String) -> Self {
134 let string = Self::from(source.as_str());
135
136 unsafe { zero(source.as_mut_ptr(), source.len()); }
138
139 string
140 }
141}
142
143impl Ref<'_> {
144 #[must_use] #[inline]
145 pub fn as_bytes(&self) -> &[u8] {
146 self.0.as_slice()
147 }
148
149 #[must_use] #[inline]
150 pub fn as_str(&self) -> &str {
151 unsafe { std::str::from_utf8_unchecked(self.0.as_slice()) }
152 }
153
154 #[inline]
155 pub fn chars(&self) -> Chars<'_> {
156 self.as_str().chars()
157 }
158}
159
160impl PartialEq<Self> for Ref<'_> {
161 #[inline]
162 fn eq(&self, other: &Self) -> bool {
163 String::eq_slice(unsafe { self.0.0.inner() }, unsafe { other.0.0.inner() })
164 }
165}
166
167impl PartialEq<RefMut<'_>> for Ref<'_> {
168 #[inline]
169 fn eq(&self, other: &RefMut<'_>) -> bool {
170 String::eq_slice(unsafe { self.0.0.inner() }, unsafe { other.0.0.inner() })
171 }
172}
173
174impl RefMut<'_> {
175 #[must_use] #[inline]
176 pub fn as_bytes(&self) -> &[u8] {
177 self.0.as_slice()
178 }
179
180 #[must_use] #[inline]
181 pub fn as_str(&self) -> &str {
182 unsafe { std::str::from_utf8_unchecked(self.0.as_slice()) }
183 }
184
185 #[inline]
186 pub fn chars(&self) -> Chars<'_> {
187 self.as_str().chars()
188 }
189
190 #[inline]
191 pub fn reserve(&mut self, capacity: usize) {
192 self.0.reserve(capacity);
193 }
194
195 #[inline]
196 pub fn reserve_exact(&mut self, capacity: usize) {
197 self.0.reserve_exact(capacity);
198 }
199
200 pub fn push(&mut self, ch: char) {
201 decompose_canonical(ch, |decomp| {
202 self.0.0.reserve(decomp.len_utf8());
203 decomp.encode_utf8(unsafe { MaybeUninit::slice_assume_init_mut(self.0.spare_capacity_mut()) });
204 unsafe { self.0.0.set_len(self.0.len() + decomp.len_utf8()); }
205 });
206 }
207
208 pub fn push_str(&mut self, string: &str) {
209 let iter = string.nfd();
210 let (lower, upper) = iter.size_hint();
211
212 self.0.0.reserve(upper.unwrap_or(lower));
213
214 for decomp in iter {
215 self.0.0.reserve(decomp.len_utf8());
216 decomp.encode_utf8(unsafe { MaybeUninit::slice_assume_init_mut(self.0.spare_capacity_mut()) });
217 unsafe { self.0.0.set_len(self.0.len() + decomp.len_utf8()); }
218 }
219 }
220
221 pub fn pop(&mut self) -> Option<char> {
222 let ch = self.chars().next_back()?;
223 unsafe { self.0.0.set_len(self.0.len() - ch.len_utf8()); }
224 unsafe { zero(self.0.as_mut_ptr().add(self.0.len()), ch.len_utf8()); }
225 Some(ch)
226 }
227}
228
229impl PartialEq<Self> for RefMut<'_> {
230 #[inline]
231 fn eq(&self, other: &Self) -> bool {
232 String::eq_slice(unsafe { self.0.0.inner() }, unsafe { other.0.0.inner() })
233 }
234}
235
236impl PartialEq<Ref<'_>> for RefMut<'_> {
237 #[inline]
238 fn eq(&self, other: &Ref<'_>) -> bool {
239 String::eq_slice(unsafe { self.0.0.inner() }, unsafe { other.0.0.inner() })
240 }
241}
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246
247 #[test]
248 fn eq() {
249 assert_eq!(String::from("").borrow(), String::from("").borrow());
250 assert_eq!(String::from("ÄÖÜäöüß").borrow(), String::from("A\u{308}O\u{308}U\u{308}a\u{308}o\u{308}u\u{308}ß").borrow());
251
252 assert_ne!(String::from("empty").borrow(), String::from("").borrow());
253 assert_ne!(String::from("Warum Thunfische das?").borrow(), String::from("Darum Thunfische das!").borrow());
254 }
255
256 #[test]
257 fn pop() {
258 let mut string = String::from("Warum Thunfische das?");
259 let mut immutable = string.borrow_mut();
260
261 assert_eq!(immutable.pop(), Some('?'));
262 assert_eq!(immutable.pop(), Some('s'));
263 assert_eq!(immutable.pop(), Some('a'));
264 assert_eq!(immutable.pop(), Some('d'));
265 assert_eq!(immutable.pop(), Some(' '));
266 assert_eq!(immutable, String::from("Warum Thunfische").borrow());
267 }
268}