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