1#[cfg(feature = "alloc")]
4use alloc::borrow::Cow;
5#[cfg(feature = "alloc")]
6use alloc::boxed::Box;
7#[cfg(feature = "alloc")]
8use alloc::rc::Rc;
9#[cfg(feature = "alloc")]
10use alloc::string::String;
11#[cfg(feature = "alloc")]
12use core::mem;
13#[cfg(feature = "alloc")]
14use alloc::sync::Arc;
15use core::fmt;
16use core::str;
17
18use crate::lossy::Utf8Lossy;
19use crate::os_str::OsStr;
20use crate::sys_common::AsInner;
21use crate::sys_common::bytestring::debug_fmt_bytestring;
22
23pub(crate) struct Slice {
24 pub inner: [u8],
25}
26
27impl fmt::Debug for Slice {
28 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29 debug_fmt_bytestring(&self.inner, formatter)
30 }
31}
32
33impl fmt::Display for Slice {
34 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
35 fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
36 }
37}
38
39#[cfg(feature = "alloc")]
40pub mod inner_alloc {
41 use alloc::boxed::Box;
42 use alloc::rc::Rc;
43 use alloc::string::String;
44 use alloc::sync::Arc;
45 use alloc::vec::Vec;
46 use core::fmt;
47 use core::mem;
48
49 use crate::os_str::OsString;
50 use crate::sys_common::{AsInner, FromInner, IntoInner};
51
52 use super::Slice;
53
54 #[derive(Clone, Hash)]
55 pub(crate) struct Buf {
56 pub inner: Vec<u8>,
57 }
58
59 impl fmt::Debug for Buf {
60 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Debug::fmt(self.as_slice(), formatter)
62 }
63 }
64
65 impl fmt::Display for Buf {
66 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
67 fmt::Display::fmt(self.as_slice(), formatter)
68 }
69 }
70
71 impl IntoInner<Vec<u8>> for Buf {
72 fn into_inner(self) -> Vec<u8> {
73 self.inner
74 }
75 }
76
77 impl AsInner<[u8]> for Buf {
78 fn as_inner(&self) -> &[u8] {
79 &self.inner
80 }
81 }
82
83 impl Buf {
84 pub fn from_string(s: String) -> Buf {
85 Buf {
86 inner: s.into_bytes(),
87 }
88 }
89
90 #[inline]
91 pub fn with_capacity(capacity: usize) -> Buf {
92 Buf {
93 inner: Vec::with_capacity(capacity),
94 }
95 }
96
97 #[inline]
98 pub fn clear(&mut self) {
99 self.inner.clear()
100 }
101
102 #[inline]
103 pub fn capacity(&self) -> usize {
104 self.inner.capacity()
105 }
106
107 #[inline]
108 pub fn reserve(&mut self, additional: usize) {
109 self.inner.reserve(additional)
110 }
111
112 #[inline]
113 pub fn reserve_exact(&mut self, additional: usize) {
114 self.inner.reserve_exact(additional)
115 }
116
117 #[inline]
118 pub fn shrink_to_fit(&mut self) {
119 self.inner.shrink_to_fit()
120 }
121
122pub fn as_slice(&self) -> &Slice {
128 unsafe { &*(&*self.inner as *const [u8] as *const _) }
129 }
130
131 pub fn into_string(self) -> Result<String, Buf> {
132 String::from_utf8(self.inner).map_err(|p| Buf {
133 inner: p.into_bytes(),
134 })
135 }
136
137 pub fn push_slice(&mut self, s: &Slice) {
138 self.inner.extend_from_slice(&s.inner)
139 }
140
141 #[inline]
142 pub fn into_box(self) -> Box<Slice> {
143 unsafe { mem::transmute(self.inner.into_boxed_slice()) }
144 }
145
146 #[inline]
147 pub fn from_box(boxed: Box<Slice>) -> Buf {
148 let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
149 Buf {
150 inner: inner.into_vec(),
151 }
152 }
153
154 #[inline]
155 pub fn into_arc(&self) -> Arc<Slice> {
156 self.as_slice().into_arc()
157 }
158
159 #[inline]
160 pub fn into_rc(&self) -> Rc<Slice> {
161 self.as_slice().into_rc()
162 }
163 }
164
165 pub trait OsStringExt {
169 fn from_vec(vec: Vec<u8>) -> Self;
175
176 fn into_vec(self) -> Vec<u8>;
182 }
183
184 impl OsStringExt for OsString {
185 fn from_vec(vec: Vec<u8>) -> OsString {
186 FromInner::from_inner(Buf { inner: vec })
187 }
188 fn into_vec(self) -> Vec<u8> {
189 self.into_inner().inner
190 }
191 }
192}
193
194impl Slice {
195 fn from_u8_slice(s: &[u8]) -> &Slice {
196 unsafe { &*(s as *const [u8] as *const _) }
197 }
198
199 pub fn from_str(s: &str) -> &Slice {
200 Slice::from_u8_slice(s.as_bytes())
201 }
202
203 pub fn to_str(&self) -> Option<&str> {
204 str::from_utf8(&self.inner).ok()
205 }
206
207 #[cfg(feature = "alloc")]
208 pub fn to_string_lossy(&self) -> Cow<'_, str> {
209 String::from_utf8_lossy(&self.inner)
210 }
211
212 #[cfg(feature = "alloc")]
213 pub fn to_owned(&self) -> self::inner_alloc::Buf {
214 self::inner_alloc::Buf {
215 inner: self.inner.to_vec(),
216 }
217 }
218
219 #[cfg(feature = "alloc")]
220 #[inline]
221 pub fn into_box(&self) -> Box<Slice> {
222 let boxed: Box<[u8]> = self.inner.into();
223 unsafe { mem::transmute(boxed) }
224 }
225
226 #[cfg(feature = "alloc")]
227 pub fn empty_box() -> Box<Slice> {
228 let boxed: Box<[u8]> = Default::default();
229 unsafe { mem::transmute(boxed) }
230 }
231
232 #[cfg(feature = "alloc")]
233 #[inline]
234 pub fn into_arc(&self) -> Arc<Slice> {
235 let arc: Arc<[u8]> = Arc::from(&self.inner);
236 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
237 }
238
239 #[cfg(feature = "alloc")]
240 #[inline]
241 pub fn into_rc(&self) -> Rc<Slice> {
242 let rc: Rc<[u8]> = Rc::from(&self.inner);
243 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
244 }
245}
246
247pub trait OsStrExt {
251 fn from_bytes(slice: &[u8]) -> &Self;
257
258 fn as_bytes(&self) -> &[u8];
264}
265
266impl OsStrExt for OsStr {
267 #[inline]
268 fn from_bytes(slice: &[u8]) -> &OsStr {
269 unsafe { &*(slice as *const [u8] as *const _) }
270 }
271 #[inline]
272 fn as_bytes(&self) -> &[u8] {
273 &self.as_inner().inner
274 }
275}