1use crate::sys_common::bytestring::debug_fmt_bytestring;
4#[cfg(feature = "alloc")]
5use crate::sys_common::{AsInner, IntoInner};
6use core::fmt;
7use core::mem;
8use core::str;
9
10#[cfg(feature = "alloc")]
11use alloc::borrow::Cow;
12#[cfg(feature = "alloc")]
13use alloc::boxed::Box;
14#[cfg(feature = "alloc")]
15use alloc::rc::Rc;
16#[cfg(feature = "alloc")]
17use alloc::string::String;
18#[cfg(feature = "alloc")]
19use alloc::sync::Arc;
20#[cfg(feature = "alloc")]
21use alloc::vec::Vec;
22
23#[cfg(all(feature = "alloc", feature = "toowned_clone_into"))]
24use alloc::borrow::ToOwned;
25
26#[cfg(feature = "alloc")]
27#[derive(Clone, Hash)]
28pub(crate) struct Buf {
29 pub inner: Vec<u8>,
30}
31
32pub(crate) struct Slice {
39 pub inner: [u8],
40}
41
42impl fmt::Debug for Slice {
43 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44 debug_fmt_bytestring(&self.inner, formatter)
45 }
46}
47
48#[cfg(feature = "alloc")]
49impl IntoInner<Vec<u8>> for Buf {
50 fn into_inner(self) -> Vec<u8> {
51 self.inner
52 }
53}
54
55#[cfg(feature = "alloc")]
56impl AsInner<[u8]> for Buf {
57 fn as_inner(&self) -> &[u8] {
58 &self.inner
59 }
60}
61
62#[cfg(feature = "alloc")]
63impl Buf {
64 pub fn from_string(s: String) -> Self {
65 Self {
66 inner: s.into_bytes(),
67 }
68 }
69
70 #[inline]
71 pub fn with_capacity(capacity: usize) -> Self {
72 Buf {
73 inner: Vec::with_capacity(capacity),
74 }
75 }
76
77 #[inline]
78 pub fn clear(&mut self) {
79 self.inner.clear()
80 }
81
82 #[inline]
83 pub fn capacity(&self) -> usize {
84 self.inner.capacity()
85 }
86
87 #[inline]
88 pub fn reserve(&mut self, additional: usize) {
89 self.inner.reserve(additional)
90 }
91
92 #[inline]
93 pub fn reserve_exact(&mut self, additional: usize) {
94 self.inner.reserve_exact(additional)
95 }
96
97 #[inline]
98 pub fn shrink_to_fit(&mut self) {
99 self.inner.shrink_to_fit()
100 }
101
102 #[inline]
103 #[cfg(feature = "shrink_to")]
104 pub fn shrink_to(&mut self, min_capacity: usize) {
105 self.inner.shrink_to(min_capacity)
106 }
107
108 #[inline]
109 pub fn as_slice(&self) -> &Slice {
110 unsafe { mem::transmute(&*self.inner) }
114 }
115
116 #[inline]
117 pub fn as_mut_slice(&mut self) -> &mut Slice {
118 unsafe { mem::transmute(&mut *self.inner) }
122 }
123
124 pub fn into_string(self) -> Result<String, Self> {
125 String::from_utf8(self.inner).map_err(|p| Self {
126 inner: p.into_bytes(),
127 })
128 }
129
130 pub fn push_slice(&mut self, s: &Slice) {
131 self.inner.extend_from_slice(&s.inner)
132 }
133
134 #[inline]
135 pub fn into_box(self) -> Box<Slice> {
136 unsafe { mem::transmute(self.inner.into_boxed_slice()) }
137 }
138
139 #[inline]
140 pub fn from_box(boxed: Box<Slice>) -> Self {
141 let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
142 Self {
143 inner: inner.into_vec(),
144 }
145 }
146
147 #[inline]
148 pub fn into_arc(&self) -> Arc<Slice> {
149 self.as_slice().into_arc()
150 }
151
152 #[inline]
153 pub fn into_rc(&self) -> Rc<Slice> {
154 self.as_slice().into_rc()
155 }
156}
157
158impl Slice {
159 #[inline]
160 fn from_u8_slice(s: &[u8]) -> &Self {
161 unsafe { mem::transmute(s) }
162 }
163
164 #[inline]
165 pub fn from_str(s: &str) -> &Self {
166 Self::from_u8_slice(s.as_bytes())
167 }
168
169 pub fn to_str(&self) -> Option<&str> {
170 str::from_utf8(&self.inner).ok()
171 }
172
173 #[cfg(feature = "alloc")]
174 pub fn to_string_lossy(&self) -> Cow<'_, str> {
175 String::from_utf8_lossy(&self.inner)
176 }
177
178 #[cfg(feature = "alloc")]
179 pub fn to_owned(&self) -> Buf {
180 Buf {
181 inner: self.inner.to_vec(),
182 }
183 }
184
185 #[cfg(all(feature = "alloc", feature = "toowned_clone_into"))]
186 pub fn clone_into(&self, buf: &mut Buf) {
187 self.inner.clone_into(&mut buf.inner)
188 }
189
190 #[inline]
191 #[cfg(feature = "alloc")]
192 pub fn into_box(&self) -> Box<Self> {
193 let boxed: Box<[u8]> = self.inner.into();
194 unsafe { mem::transmute(boxed) }
195 }
196
197 #[cfg(feature = "alloc")]
198 pub fn empty_box() -> Box<Self> {
199 let boxed: Box<[u8]> = Default::default();
200 unsafe { mem::transmute(boxed) }
201 }
202
203 #[inline]
204 #[cfg(feature = "alloc")]
205 pub fn into_arc(&self) -> Arc<Self> {
206 let arc: Arc<[u8]> = Arc::from(&self.inner);
207 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Self) }
208 }
209
210 #[inline]
211 #[cfg(feature = "alloc")]
212 pub fn into_rc(&self) -> Rc<Self> {
213 let rc: Rc<[u8]> = Rc::from(&self.inner);
214 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Self) }
215 }
216
217 #[inline]
218 #[cfg(feature = "unixstring_ascii")]
219 pub fn make_ascii_lowercase(&mut self) {
220 self.inner.make_ascii_lowercase()
221 }
222
223 #[inline]
224 #[cfg(feature = "unixstring_ascii")]
225 pub fn make_ascii_uppercase(&mut self) {
226 self.inner.make_ascii_uppercase()
227 }
228
229 #[inline]
230 #[cfg(all(feature = "alloc", feature = "unixstring_ascii"))]
231 pub fn to_ascii_lowercase(&self) -> Buf {
232 Buf {
233 inner: self.inner.to_ascii_lowercase(),
234 }
235 }
236
237 #[inline]
238 #[cfg(all(feature = "alloc", feature = "unixstring_ascii"))]
239 pub fn to_ascii_uppercase(&self) -> Buf {
240 Buf {
241 inner: self.inner.to_ascii_uppercase(),
242 }
243 }
244
245 #[inline]
246 #[cfg(feature = "unixstring_ascii")]
247 pub fn is_ascii(&self) -> bool {
248 self.inner.is_ascii()
249 }
250
251 #[inline]
252 #[cfg(feature = "unixstring_ascii")]
253 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
254 self.inner.eq_ignore_ascii_case(&other.inner)
255 }
256}