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(#[automatically_derived]
impl ::core::hash::Hash for Buf {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.inner, state)
}
}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 self.try_check_public_boundary(index).is_none() {
242 {
::core::panicking::panic_fmt(format_args!("byte index {0} is not an OsStr boundary",
index));
};panic!("byte index {index} is not an OsStr boundary");
243 }
244 }
245
246 #[track_caller]
247 #[inline]
248 pub fn try_check_public_boundary(&self, index: usize) -> Option<()> {
249 if index == 0 || index == self.inner.len() {
250 return Some(());
251 }
252 if index < self.inner.len()
253 && (self.inner[index - 1].is_ascii() || self.inner[index].is_ascii())
254 {
255 return Some(());
256 }
257
258 return slow_path(&self.inner, index);
259
260 #[track_caller]
265 #[inline(never)]
266 fn slow_path(bytes: &[u8], index: usize) -> Option<()> {
267 let (before, after) = bytes.split_at_checked(index)?;
268
269 let after = after.get(..4).unwrap_or(after);
272 match str::from_utf8(after) {
273 Ok(_) => return Some(()),
274 Err(err) if err.valid_up_to() != 0 => return Some(()),
275 Err(_) => (),
276 }
277
278 for len in 2..=4.min(index) {
279 let before = &before[index - len..];
280 if str::from_utf8(before).is_ok() {
281 return Some(());
282 }
283 }
284
285 None
286 }
287 }
288
289 #[inline]
290 pub fn from_str(s: &str) -> &Slice {
291 unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
292 }
293
294 #[inline]
295 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
296 str::from_utf8(&self.inner)
297 }
298
299 #[inline]
300 pub fn to_string_lossy(&self) -> Cow<'_, str> {
301 String::from_utf8_lossy(&self.inner)
302 }
303
304 #[inline]
305 pub fn to_owned(&self) -> Buf {
306 Buf { inner: self.inner.to_vec() }
307 }
308
309 #[inline]
310 pub fn clone_into(&self, buf: &mut Buf) {
311 self.inner.clone_into(&mut buf.inner)
312 }
313
314 #[inline]
315 pub fn empty_box() -> Box<Slice> {
316 let boxed: Box<[u8]> = Default::default();
317 unsafe { mem::transmute(boxed) }
318 }
319
320 #[inline]
321 pub fn into_arc(&self) -> Arc<Slice> {
322 let arc: Arc<[u8]> = Arc::from(&self.inner);
323 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
324 }
325
326 #[inline]
327 pub fn into_rc(&self) -> Rc<Slice> {
328 let rc: Rc<[u8]> = Rc::from(&self.inner);
329 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
330 }
331
332 #[inline]
333 pub fn make_ascii_lowercase(&mut self) {
334 self.inner.make_ascii_lowercase()
335 }
336
337 #[inline]
338 pub fn make_ascii_uppercase(&mut self) {
339 self.inner.make_ascii_uppercase()
340 }
341
342 #[inline]
343 pub fn to_ascii_lowercase(&self) -> Buf {
344 Buf { inner: self.inner.to_ascii_lowercase() }
345 }
346
347 #[inline]
348 pub fn to_ascii_uppercase(&self) -> Buf {
349 Buf { inner: self.inner.to_ascii_uppercase() }
350 }
351
352 #[inline]
353 pub fn is_ascii(&self) -> bool {
354 self.inner.is_ascii()
355 }
356
357 #[inline]
358 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
359 self.inner.eq_ignore_ascii_case(&other.inner)
360 }
361}
362
363#[unstable(feature = "clone_to_uninit", issue = "126799")]
364unsafe impl CloneToUninit for Slice {
365 #[inline]
366 #[cfg_attr(debug_assertions, track_caller)]
367 unsafe fn clone_to_uninit(&self, dst: *mut u8) {
368 unsafe { self.inner.clone_to_uninit(dst) }
370 }
371}