1use core::clone::CloneToUninit;
4
5use crate::borrow::Cow;
6use crate::collections::TryReserveError;
7use crate::rc::Rc;
8use crate::sync::Arc;
9use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary};
10use crate::sys_common::{AsInner, FromInner, IntoInner};
11use crate::{fmt, mem};
12
13#[derive(Hash)]
14pub struct Buf {
15 pub inner: Wtf8Buf,
16}
17
18#[repr(transparent)]
19pub struct Slice {
20 pub inner: Wtf8,
21}
22
23impl IntoInner<Wtf8Buf> for Buf {
24 fn into_inner(self) -> Wtf8Buf {
25 self.inner
26 }
27}
28
29impl FromInner<Wtf8Buf> for Buf {
30 fn from_inner(inner: Wtf8Buf) -> Self {
31 Buf { inner }
32 }
33}
34
35impl AsInner<Wtf8> for Buf {
36 #[inline]
37 fn as_inner(&self) -> &Wtf8 {
38 &self.inner
39 }
40}
41
42impl fmt::Debug for Buf {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 fmt::Debug::fmt(&self.inner, f)
45 }
46}
47
48impl fmt::Display for Buf {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 fmt::Display::fmt(&self.inner, f)
51 }
52}
53
54impl fmt::Debug for Slice {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 fmt::Debug::fmt(&self.inner, f)
57 }
58}
59
60impl fmt::Display for Slice {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 fmt::Display::fmt(&self.inner, f)
63 }
64}
65
66impl Clone for Buf {
67 #[inline]
68 fn clone(&self) -> Self {
69 Buf { inner: self.inner.clone() }
70 }
71
72 #[inline]
73 fn clone_from(&mut self, source: &Self) {
74 self.inner.clone_from(&source.inner)
75 }
76}
77
78impl Buf {
79 #[inline]
80 pub fn into_encoded_bytes(self) -> Vec<u8> {
81 self.inner.into_bytes()
82 }
83
84 #[inline]
85 pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
86 unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } }
87 }
88
89 #[inline]
90 pub fn into_string(self) -> Result<String, Buf> {
91 self.inner.into_string().map_err(|buf| Buf { inner: buf })
92 }
93
94 #[inline]
95 pub const fn from_string(s: String) -> Buf {
96 Buf { inner: Wtf8Buf::from_string(s) }
97 }
98
99 #[inline]
100 pub fn with_capacity(capacity: usize) -> Buf {
101 Buf { inner: Wtf8Buf::with_capacity(capacity) }
102 }
103
104 #[inline]
105 pub fn clear(&mut self) {
106 self.inner.clear()
107 }
108
109 #[inline]
110 pub fn capacity(&self) -> usize {
111 self.inner.capacity()
112 }
113
114 #[inline]
115 pub fn push_slice(&mut self, s: &Slice) {
116 self.inner.push_wtf8(&s.inner)
117 }
118
119 #[inline]
120 pub fn push_str(&mut self, s: &str) {
121 self.inner.push_str(s);
122 }
123
124 #[inline]
125 pub fn reserve(&mut self, additional: usize) {
126 self.inner.reserve(additional)
127 }
128
129 #[inline]
130 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
131 self.inner.try_reserve(additional)
132 }
133
134 #[inline]
135 pub fn reserve_exact(&mut self, additional: usize) {
136 self.inner.reserve_exact(additional)
137 }
138
139 #[inline]
140 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
141 self.inner.try_reserve_exact(additional)
142 }
143
144 #[inline]
145 pub fn shrink_to_fit(&mut self) {
146 self.inner.shrink_to_fit()
147 }
148
149 #[inline]
150 pub fn shrink_to(&mut self, min_capacity: usize) {
151 self.inner.shrink_to(min_capacity)
152 }
153
154 #[inline]
155 pub fn as_slice(&self) -> &Slice {
156 unsafe { mem::transmute(self.inner.as_slice()) }
160 }
161
162 #[inline]
163 pub fn as_mut_slice(&mut self) -> &mut Slice {
164 unsafe { mem::transmute(self.inner.as_mut_slice()) }
170 }
171
172 #[inline]
173 pub fn leak<'a>(self) -> &'a mut Slice {
174 unsafe { mem::transmute(self.inner.leak()) }
175 }
176
177 #[inline]
178 pub fn into_box(self) -> Box<Slice> {
179 unsafe { mem::transmute(self.inner.into_box()) }
180 }
181
182 #[inline]
183 pub fn from_box(boxed: Box<Slice>) -> Buf {
184 let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
185 Buf { inner: Wtf8Buf::from_box(inner) }
186 }
187
188 #[inline]
189 pub fn into_arc(&self) -> Arc<Slice> {
190 self.as_slice().into_arc()
191 }
192
193 #[inline]
194 pub fn into_rc(&self) -> Rc<Slice> {
195 self.as_slice().into_rc()
196 }
197
198 #[inline]
206 pub unsafe fn truncate_unchecked(&mut self, len: usize) {
207 self.inner.truncate(len);
208 }
209
210 #[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.as_bytes()
231 }
232
233 #[inline]
234 pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
235 unsafe { mem::transmute(Wtf8::from_bytes_unchecked(s)) }
236 }
237
238 #[track_caller]
239 #[inline]
240 pub fn check_public_boundary(&self, index: usize) {
241 check_utf8_boundary(&self.inner, index);
242 }
243
244 #[inline]
245 pub fn from_str(s: &str) -> &Slice {
246 unsafe { mem::transmute(Wtf8::from_str(s)) }
247 }
248
249 #[inline]
250 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
251 self.inner.as_str()
252 }
253
254 #[inline]
255 pub fn to_string_lossy(&self) -> Cow<'_, str> {
256 self.inner.to_string_lossy()
257 }
258
259 #[inline]
260 pub fn to_owned(&self) -> Buf {
261 Buf { inner: self.inner.to_owned() }
262 }
263
264 #[inline]
265 pub fn clone_into(&self, buf: &mut Buf) {
266 self.inner.clone_into(&mut buf.inner)
267 }
268
269 #[inline]
270 pub fn into_box(&self) -> Box<Slice> {
271 unsafe { mem::transmute(self.inner.into_box()) }
272 }
273
274 #[inline]
275 pub fn empty_box() -> Box<Slice> {
276 unsafe { mem::transmute(Wtf8::empty_box()) }
277 }
278
279 #[inline]
280 pub fn into_arc(&self) -> Arc<Slice> {
281 let arc = self.inner.into_arc();
282 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
283 }
284
285 #[inline]
286 pub fn into_rc(&self) -> Rc<Slice> {
287 let rc = self.inner.into_rc();
288 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
289 }
290
291 #[inline]
292 pub fn make_ascii_lowercase(&mut self) {
293 self.inner.make_ascii_lowercase()
294 }
295
296 #[inline]
297 pub fn make_ascii_uppercase(&mut self) {
298 self.inner.make_ascii_uppercase()
299 }
300
301 #[inline]
302 pub fn to_ascii_lowercase(&self) -> Buf {
303 Buf { inner: self.inner.to_ascii_lowercase() }
304 }
305
306 #[inline]
307 pub fn to_ascii_uppercase(&self) -> Buf {
308 Buf { inner: self.inner.to_ascii_uppercase() }
309 }
310
311 #[inline]
312 pub fn is_ascii(&self) -> bool {
313 self.inner.is_ascii()
314 }
315
316 #[inline]
317 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
318 self.inner.eq_ignore_ascii_case(&other.inner)
319 }
320}
321
322#[unstable(feature = "clone_to_uninit", issue = "126799")]
323unsafe impl CloneToUninit for Slice {
324 #[inline]
325 #[cfg_attr(debug_assertions, track_caller)]
326 unsafe fn clone_to_uninit(&self, dst: *mut u8) {
327 unsafe { self.inner.clone_to_uninit(dst) }
329 }
330}