1use core::clone::CloneToUninit;
5
6use crate::borrow::Cow;
7use crate::bstr::ByteStr;
8use crate::collections::TryReserveError;
9use crate::rc::Rc;
10use crate::sync::Arc;
11use crate::sys::{AsInner, FromInner, IntoInner};
12use crate::{fmt, mem, str};
13
14#[cfg(test)]
15mod tests;
16
17#[derive(Hash)]
18#[repr(transparent)]
19pub struct Buf {
20 pub inner: Vec<u8>,
21}
22
23#[repr(transparent)]
24pub struct Slice {
25 pub inner: [u8],
26}
27
28impl IntoInner<Vec<u8>> for Buf {
29 fn into_inner(self) -> Vec<u8> {
30 self.inner
31 }
32}
33
34impl FromInner<Vec<u8>> for Buf {
35 fn from_inner(inner: Vec<u8>) -> Self {
36 Buf { inner }
37 }
38}
39
40impl AsInner<[u8]> for Buf {
41 #[inline]
42 fn as_inner(&self) -> &[u8] {
43 &self.inner
44 }
45}
46
47impl fmt::Debug for Buf {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 fmt::Debug::fmt(self.as_slice(), f)
50 }
51}
52
53impl fmt::Display for Buf {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 fmt::Display::fmt(self.as_slice(), f)
56 }
57}
58
59impl fmt::Debug for Slice {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f)
62 }
63}
64
65impl fmt::Display for Slice {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 fmt::Display::fmt(ByteStr::new(&self.inner), f)
68 }
69}
70
71impl Clone for Buf {
72 #[inline]
73 fn clone(&self) -> Self {
74 Buf { inner: self.inner.clone() }
75 }
76
77 #[inline]
78 fn clone_from(&mut self, source: &Self) {
79 self.inner.clone_from(&source.inner)
80 }
81}
82
83impl Buf {
84 #[inline]
85 pub fn into_encoded_bytes(self) -> Vec<u8> {
86 self.inner
87 }
88
89 #[inline]
90 pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
91 Self { inner: s }
92 }
93
94 #[inline]
95 pub fn into_string(self) -> Result<String, Buf> {
96 String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
97 }
98
99 #[inline]
100 pub const fn from_string(s: String) -> Buf {
101 Buf { inner: s.into_bytes() }
102 }
103
104 #[inline]
105 pub fn with_capacity(capacity: usize) -> Buf {
106 Buf { inner: Vec::with_capacity(capacity) }
107 }
108
109 #[inline]
110 pub fn clear(&mut self) {
111 self.inner.clear()
112 }
113
114 #[inline]
115 pub fn capacity(&self) -> usize {
116 self.inner.capacity()
117 }
118
119 #[inline]
120 pub fn push_slice(&mut self, s: &Slice) {
121 self.inner.extend_from_slice(&s.inner)
122 }
123
124 #[inline]
125 pub fn push_str(&mut self, s: &str) {
126 self.inner.extend_from_slice(s.as_bytes());
127 }
128
129 #[inline]
130 pub fn reserve(&mut self, additional: usize) {
131 self.inner.reserve(additional)
132 }
133
134 #[inline]
135 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
136 self.inner.try_reserve(additional)
137 }
138
139 #[inline]
140 pub fn reserve_exact(&mut self, additional: usize) {
141 self.inner.reserve_exact(additional)
142 }
143
144 #[inline]
145 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
146 self.inner.try_reserve_exact(additional)
147 }
148
149 #[inline]
150 pub fn shrink_to_fit(&mut self) {
151 self.inner.shrink_to_fit()
152 }
153
154 #[inline]
155 pub fn shrink_to(&mut self, min_capacity: usize) {
156 self.inner.shrink_to(min_capacity)
157 }
158
159 #[inline]
160 pub fn as_slice(&self) -> &Slice {
161 unsafe { mem::transmute(self.inner.as_slice()) }
165 }
166
167 #[inline]
168 pub fn as_mut_slice(&mut self) -> &mut Slice {
169 unsafe { mem::transmute(self.inner.as_mut_slice()) }
173 }
174
175 #[inline]
176 pub fn leak<'a>(self) -> &'a mut Slice {
177 unsafe { mem::transmute(self.inner.leak()) }
178 }
179
180 #[inline]
181 pub fn into_box(self) -> Box<Slice> {
182 unsafe { mem::transmute(self.inner.into_boxed_slice()) }
183 }
184
185 #[inline]
186 pub fn from_box(boxed: Box<Slice>) -> Buf {
187 let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
188 Buf { inner: inner.into_vec() }
189 }
190
191 #[inline]
192 pub fn into_arc(&self) -> Arc<Slice> {
193 self.as_slice().into_arc()
194 }
195
196 #[inline]
197 pub fn into_rc(&self) -> Rc<Slice> {
198 self.as_slice().into_rc()
199 }
200
201 #[inline]
209 pub unsafe fn truncate_unchecked(&mut self, len: usize) {
210 self.inner.truncate(len);
211 }
212
213 #[inline]
222 pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
223 self.inner.extend_from_slice(other);
224 }
225}
226
227impl Slice {
228 #[inline]
229 pub fn as_encoded_bytes(&self) -> &[u8] {
230 &self.inner
231 }
232
233 #[inline]
234 pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
235 unsafe { mem::transmute(s) }
236 }
237
238 #[track_caller]
239 #[inline]
240 pub fn check_public_boundary(&self, index: usize) {
241 if index == 0 || index == self.inner.len() {
242 return;
243 }
244 if index < self.inner.len()
245 && (self.inner[index - 1].is_ascii() || self.inner[index].is_ascii())
246 {
247 return;
248 }
249
250 slow_path(&self.inner, index);
251
252 #[track_caller]
257 #[inline(never)]
258 fn slow_path(bytes: &[u8], index: usize) {
259 let (before, after) = bytes.split_at(index);
260
261 let after = after.get(..4).unwrap_or(after);
264 match str::from_utf8(after) {
265 Ok(_) => return,
266 Err(err) if err.valid_up_to() != 0 => return,
267 Err(_) => (),
268 }
269
270 for len in 2..=4.min(index) {
271 let before = &before[index - len..];
272 if str::from_utf8(before).is_ok() {
273 return;
274 }
275 }
276
277 panic!("byte index {index} is not an OsStr boundary");
278 }
279 }
280
281 #[inline]
282 pub fn from_str(s: &str) -> &Slice {
283 unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
284 }
285
286 #[inline]
287 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
288 str::from_utf8(&self.inner)
289 }
290
291 #[inline]
292 pub fn to_string_lossy(&self) -> Cow<'_, str> {
293 String::from_utf8_lossy(&self.inner)
294 }
295
296 #[inline]
297 pub fn to_owned(&self) -> Buf {
298 Buf { inner: self.inner.to_vec() }
299 }
300
301 #[inline]
302 pub fn clone_into(&self, buf: &mut Buf) {
303 self.inner.clone_into(&mut buf.inner)
304 }
305
306 #[inline]
307 pub fn empty_box() -> Box<Slice> {
308 let boxed: Box<[u8]> = Default::default();
309 unsafe { mem::transmute(boxed) }
310 }
311
312 #[inline]
313 pub fn into_arc(&self) -> Arc<Slice> {
314 let arc: Arc<[u8]> = Arc::from(&self.inner);
315 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
316 }
317
318 #[inline]
319 pub fn into_rc(&self) -> Rc<Slice> {
320 let rc: Rc<[u8]> = Rc::from(&self.inner);
321 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
322 }
323
324 #[inline]
325 pub fn make_ascii_lowercase(&mut self) {
326 self.inner.make_ascii_lowercase()
327 }
328
329 #[inline]
330 pub fn make_ascii_uppercase(&mut self) {
331 self.inner.make_ascii_uppercase()
332 }
333
334 #[inline]
335 pub fn to_ascii_lowercase(&self) -> Buf {
336 Buf { inner: self.inner.to_ascii_lowercase() }
337 }
338
339 #[inline]
340 pub fn to_ascii_uppercase(&self) -> Buf {
341 Buf { inner: self.inner.to_ascii_uppercase() }
342 }
343
344 #[inline]
345 pub fn is_ascii(&self) -> bool {
346 self.inner.is_ascii()
347 }
348
349 #[inline]
350 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
351 self.inner.eq_ignore_ascii_case(&other.inner)
352 }
353}
354
355#[unstable(feature = "clone_to_uninit", issue = "126799")]
356unsafe impl CloneToUninit for Slice {
357 #[inline]
358 #[cfg_attr(debug_assertions, track_caller)]
359 unsafe fn clone_to_uninit(&self, dst: *mut u8) {
360 unsafe { self.inner.clone_to_uninit(dst) }
362 }
363}