1use alloc::wtf8::{Wtf8, Wtf8Buf};
4use core::clone::CloneToUninit;
5
6use crate::borrow::Cow;
7use crate::collections::TryReserveError;
8use crate::rc::Rc;
9use crate::sync::Arc;
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 unsafe {
224 self.inner.extend_from_slice_unchecked(other);
225 }
226 }
227}
228
229impl Slice {
230 #[inline]
231 pub fn as_encoded_bytes(&self) -> &[u8] {
232 self.inner.as_bytes()
233 }
234
235 #[inline]
236 pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
237 unsafe { mem::transmute(Wtf8::from_bytes_unchecked(s)) }
238 }
239
240 #[track_caller]
241 #[inline]
242 pub fn check_public_boundary(&self, index: usize) {
243 self.inner.check_utf8_boundary(index);
244 }
245
246 #[inline]
247 pub fn from_str(s: &str) -> &Slice {
248 unsafe { mem::transmute(Wtf8::from_str(s)) }
249 }
250
251 #[inline]
252 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
253 self.inner.as_str()
254 }
255
256 #[inline]
257 pub fn to_string_lossy(&self) -> Cow<'_, str> {
258 self.inner.to_string_lossy()
259 }
260
261 #[inline]
262 pub fn to_owned(&self) -> Buf {
263 Buf { inner: self.inner.to_owned() }
264 }
265
266 #[inline]
267 pub fn clone_into(&self, buf: &mut Buf) {
268 self.inner.clone_into(&mut buf.inner)
269 }
270
271 #[inline]
272 pub fn into_box(&self) -> Box<Slice> {
273 unsafe { mem::transmute(self.inner.into_box()) }
274 }
275
276 #[inline]
277 pub fn empty_box() -> Box<Slice> {
278 unsafe { mem::transmute(Wtf8::empty_box()) }
279 }
280
281 #[inline]
282 pub fn into_arc(&self) -> Arc<Slice> {
283 let arc = self.inner.into_arc();
284 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
285 }
286
287 #[inline]
288 pub fn into_rc(&self) -> Rc<Slice> {
289 let rc = self.inner.into_rc();
290 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
291 }
292
293 #[inline]
294 pub fn make_ascii_lowercase(&mut self) {
295 self.inner.make_ascii_lowercase()
296 }
297
298 #[inline]
299 pub fn make_ascii_uppercase(&mut self) {
300 self.inner.make_ascii_uppercase()
301 }
302
303 #[inline]
304 pub fn to_ascii_lowercase(&self) -> Buf {
305 Buf { inner: self.inner.to_ascii_lowercase() }
306 }
307
308 #[inline]
309 pub fn to_ascii_uppercase(&self) -> Buf {
310 Buf { inner: self.inner.to_ascii_uppercase() }
311 }
312
313 #[inline]
314 pub fn is_ascii(&self) -> bool {
315 self.inner.is_ascii()
316 }
317
318 #[inline]
319 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
320 self.inner.eq_ignore_ascii_case(&other.inner)
321 }
322}
323
324#[unstable(feature = "clone_to_uninit", issue = "126799")]
325unsafe impl CloneToUninit for Slice {
326 #[inline]
327 #[cfg_attr(debug_assertions, track_caller)]
328 unsafe fn clone_to_uninit(&self, dst: *mut u8) {
329 unsafe { self.inner.clone_to_uninit(dst) }
331 }
332}