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(Clone, Hash)]
14pub struct Buf {
15 pub inner: Wtf8Buf,
16}
17
18impl IntoInner<Wtf8Buf> for Buf {
19 fn into_inner(self) -> Wtf8Buf {
20 self.inner
21 }
22}
23
24impl FromInner<Wtf8Buf> for Buf {
25 fn from_inner(inner: Wtf8Buf) -> Self {
26 Buf { inner }
27 }
28}
29
30impl AsInner<Wtf8> for Buf {
31 #[inline]
32 fn as_inner(&self) -> &Wtf8 {
33 &self.inner
34 }
35}
36
37impl fmt::Debug for Buf {
38 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
39 fmt::Debug::fmt(self.as_slice(), formatter)
40 }
41}
42
43impl fmt::Display for Buf {
44 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
45 fmt::Display::fmt(self.as_slice(), formatter)
46 }
47}
48
49#[repr(transparent)]
50pub struct Slice {
51 pub inner: Wtf8,
52}
53
54impl fmt::Debug for Slice {
55 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56 fmt::Debug::fmt(&self.inner, formatter)
57 }
58}
59
60impl fmt::Display for Slice {
61 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62 fmt::Display::fmt(&self.inner, formatter)
63 }
64}
65
66impl Buf {
67 #[inline]
68 pub fn into_encoded_bytes(self) -> Vec<u8> {
69 self.inner.into_bytes()
70 }
71
72 #[inline]
73 pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
74 unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } }
75 }
76
77 pub fn with_capacity(capacity: usize) -> Buf {
78 Buf { inner: Wtf8Buf::with_capacity(capacity) }
79 }
80
81 pub fn clear(&mut self) {
82 self.inner.clear()
83 }
84
85 pub fn capacity(&self) -> usize {
86 self.inner.capacity()
87 }
88
89 pub fn from_string(s: String) -> Buf {
90 Buf { inner: Wtf8Buf::from_string(s) }
91 }
92
93 pub fn as_slice(&self) -> &Slice {
94 unsafe { mem::transmute(self.inner.as_slice()) }
98 }
99
100 pub fn as_mut_slice(&mut self) -> &mut Slice {
101 unsafe { mem::transmute(self.inner.as_mut_slice()) }
107 }
108
109 pub fn into_string(self) -> Result<String, Buf> {
110 self.inner.into_string().map_err(|buf| Buf { inner: buf })
111 }
112
113 pub fn push_slice(&mut self, s: &Slice) {
114 self.inner.push_wtf8(&s.inner)
115 }
116
117 pub fn reserve(&mut self, additional: usize) {
118 self.inner.reserve(additional)
119 }
120
121 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
122 self.inner.try_reserve(additional)
123 }
124
125 pub fn reserve_exact(&mut self, additional: usize) {
126 self.inner.reserve_exact(additional)
127 }
128
129 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
130 self.inner.try_reserve_exact(additional)
131 }
132
133 pub fn shrink_to_fit(&mut self) {
134 self.inner.shrink_to_fit()
135 }
136
137 #[inline]
138 pub fn shrink_to(&mut self, min_capacity: usize) {
139 self.inner.shrink_to(min_capacity)
140 }
141
142 #[inline]
143 pub fn leak<'a>(self) -> &'a mut Slice {
144 unsafe { mem::transmute(self.inner.leak()) }
145 }
146
147 #[inline]
148 pub fn into_box(self) -> Box<Slice> {
149 unsafe { mem::transmute(self.inner.into_box()) }
150 }
151
152 #[inline]
153 pub fn from_box(boxed: Box<Slice>) -> Buf {
154 let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
155 Buf { inner: Wtf8Buf::from_box(inner) }
156 }
157
158 #[inline]
159 pub fn into_arc(&self) -> Arc<Slice> {
160 self.as_slice().into_arc()
161 }
162
163 #[inline]
164 pub fn into_rc(&self) -> Rc<Slice> {
165 self.as_slice().into_rc()
166 }
167
168 #[inline]
172 pub(crate) fn truncate(&mut self, len: usize) {
173 self.inner.truncate(len);
174 }
175
176 #[inline]
180 pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
181 self.inner.extend_from_slice(other);
182 }
183}
184
185impl Slice {
186 #[inline]
187 pub fn as_encoded_bytes(&self) -> &[u8] {
188 self.inner.as_bytes()
189 }
190
191 #[inline]
192 pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
193 unsafe { mem::transmute(Wtf8::from_bytes_unchecked(s)) }
194 }
195
196 #[track_caller]
197 pub fn check_public_boundary(&self, index: usize) {
198 check_utf8_boundary(&self.inner, index);
199 }
200
201 #[inline]
202 pub fn from_str(s: &str) -> &Slice {
203 unsafe { mem::transmute(Wtf8::from_str(s)) }
204 }
205
206 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
207 self.inner.as_str()
208 }
209
210 pub fn to_string_lossy(&self) -> Cow<'_, str> {
211 self.inner.to_string_lossy()
212 }
213
214 pub fn to_owned(&self) -> Buf {
215 Buf { inner: self.inner.to_owned() }
216 }
217
218 pub fn clone_into(&self, buf: &mut Buf) {
219 self.inner.clone_into(&mut buf.inner)
220 }
221
222 #[inline]
223 pub fn into_box(&self) -> Box<Slice> {
224 unsafe { mem::transmute(self.inner.into_box()) }
225 }
226
227 pub fn empty_box() -> Box<Slice> {
228 unsafe { mem::transmute(Wtf8::empty_box()) }
229 }
230
231 #[inline]
232 pub fn into_arc(&self) -> Arc<Slice> {
233 let arc = self.inner.into_arc();
234 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
235 }
236
237 #[inline]
238 pub fn into_rc(&self) -> Rc<Slice> {
239 let rc = self.inner.into_rc();
240 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
241 }
242
243 #[inline]
244 pub fn make_ascii_lowercase(&mut self) {
245 self.inner.make_ascii_lowercase()
246 }
247
248 #[inline]
249 pub fn make_ascii_uppercase(&mut self) {
250 self.inner.make_ascii_uppercase()
251 }
252
253 #[inline]
254 pub fn to_ascii_lowercase(&self) -> Buf {
255 Buf { inner: self.inner.to_ascii_lowercase() }
256 }
257
258 #[inline]
259 pub fn to_ascii_uppercase(&self) -> Buf {
260 Buf { inner: self.inner.to_ascii_uppercase() }
261 }
262
263 #[inline]
264 pub fn is_ascii(&self) -> bool {
265 self.inner.is_ascii()
266 }
267
268 #[inline]
269 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
270 self.inner.eq_ignore_ascii_case(&other.inner)
271 }
272}
273
274#[unstable(feature = "clone_to_uninit", issue = "126799")]
275unsafe impl CloneToUninit for Slice {
276 #[inline]
277 #[cfg_attr(debug_assertions, track_caller)]
278 unsafe fn clone_to_uninit(&self, dst: *mut u8) {
279 unsafe { self.inner.clone_to_uninit(dst) }
281 }
282}