]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys_common/os_str_bytes.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / library / std / src / sys_common / os_str_bytes.rs
1 //! The underlying OsString/OsStr implementation on Unix and many other
2 //! systems: just a `Vec<u8>`/`[u8]`.
3
4 use crate::borrow::Cow;
5 use crate::ffi::{OsStr, OsString};
6 use crate::fmt;
7 use crate::mem;
8 use crate::rc::Rc;
9 use crate::sealed::Sealed;
10 use crate::str;
11 use crate::sync::Arc;
12 use crate::sys_common::bytestring::debug_fmt_bytestring;
13 use crate::sys_common::{AsInner, FromInner, IntoInner};
14
15 use core::str::lossy::Utf8Lossy;
16
17 #[derive(Hash)]
18 pub(crate) struct Buf {
19 pub inner: Vec<u8>,
20 }
21
22 // FIXME:
23 // `Buf::as_slice` current implementation relies
24 // on `Slice` being layout-compatible with `[u8]`.
25 // When attribute privacy is implemented, `Slice` should be annotated as `#[repr(transparent)]`.
26 // Anyway, `Slice` representation and layout are considered implementation detail, are
27 // not documented and must not be relied upon.
28 pub(crate) struct Slice {
29 pub inner: [u8],
30 }
31
32 impl fmt::Debug for Slice {
33 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
34 debug_fmt_bytestring(&self.inner, formatter)
35 }
36 }
37
38 impl fmt::Display for Slice {
39 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
40 fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
41 }
42 }
43
44 impl fmt::Debug for Buf {
45 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
46 fmt::Debug::fmt(self.as_slice(), formatter)
47 }
48 }
49
50 impl fmt::Display for Buf {
51 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52 fmt::Display::fmt(self.as_slice(), formatter)
53 }
54 }
55
56 impl Clone for Buf {
57 #[inline]
58 fn clone(&self) -> Self {
59 Buf { inner: self.inner.clone() }
60 }
61
62 #[inline]
63 fn clone_from(&mut self, source: &Self) {
64 self.inner.clone_from(&source.inner)
65 }
66 }
67
68 impl IntoInner<Vec<u8>> for Buf {
69 fn into_inner(self) -> Vec<u8> {
70 self.inner
71 }
72 }
73
74 impl AsInner<[u8]> for Buf {
75 fn as_inner(&self) -> &[u8] {
76 &self.inner
77 }
78 }
79
80 impl Buf {
81 pub fn from_string(s: String) -> Buf {
82 Buf { inner: s.into_bytes() }
83 }
84
85 #[inline]
86 pub fn with_capacity(capacity: usize) -> Buf {
87 Buf { inner: Vec::with_capacity(capacity) }
88 }
89
90 #[inline]
91 pub fn clear(&mut self) {
92 self.inner.clear()
93 }
94
95 #[inline]
96 pub fn capacity(&self) -> usize {
97 self.inner.capacity()
98 }
99
100 #[inline]
101 pub fn reserve(&mut self, additional: usize) {
102 self.inner.reserve(additional)
103 }
104
105 #[inline]
106 pub fn reserve_exact(&mut self, additional: usize) {
107 self.inner.reserve_exact(additional)
108 }
109
110 #[inline]
111 pub fn shrink_to_fit(&mut self) {
112 self.inner.shrink_to_fit()
113 }
114
115 #[inline]
116 pub fn shrink_to(&mut self, min_capacity: usize) {
117 self.inner.shrink_to(min_capacity)
118 }
119
120 #[inline]
121 pub fn as_slice(&self) -> &Slice {
122 // SAFETY: Slice just wraps [u8],
123 // and &*self.inner is &[u8], therefore
124 // transmuting &[u8] to &Slice is safe.
125 unsafe { mem::transmute(&*self.inner) }
126 }
127
128 #[inline]
129 pub fn as_mut_slice(&mut self) -> &mut Slice {
130 // SAFETY: Slice just wraps [u8],
131 // and &mut *self.inner is &mut [u8], therefore
132 // transmuting &mut [u8] to &mut Slice is safe.
133 unsafe { mem::transmute(&mut *self.inner) }
134 }
135
136 pub fn into_string(self) -> Result<String, Buf> {
137 String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
138 }
139
140 pub fn push_slice(&mut self, s: &Slice) {
141 self.inner.extend_from_slice(&s.inner)
142 }
143
144 #[inline]
145 pub fn into_box(self) -> Box<Slice> {
146 unsafe { mem::transmute(self.inner.into_boxed_slice()) }
147 }
148
149 #[inline]
150 pub fn from_box(boxed: Box<Slice>) -> Buf {
151 let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
152 Buf { inner: inner.into_vec() }
153 }
154
155 #[inline]
156 pub fn into_arc(&self) -> Arc<Slice> {
157 self.as_slice().into_arc()
158 }
159
160 #[inline]
161 pub fn into_rc(&self) -> Rc<Slice> {
162 self.as_slice().into_rc()
163 }
164 }
165
166 impl Slice {
167 #[inline]
168 fn from_u8_slice(s: &[u8]) -> &Slice {
169 unsafe { mem::transmute(s) }
170 }
171
172 #[inline]
173 pub fn from_str(s: &str) -> &Slice {
174 Slice::from_u8_slice(s.as_bytes())
175 }
176
177 pub fn to_str(&self) -> Option<&str> {
178 str::from_utf8(&self.inner).ok()
179 }
180
181 pub fn to_string_lossy(&self) -> Cow<'_, str> {
182 String::from_utf8_lossy(&self.inner)
183 }
184
185 pub fn to_owned(&self) -> Buf {
186 Buf { inner: self.inner.to_vec() }
187 }
188
189 pub fn clone_into(&self, buf: &mut Buf) {
190 self.inner.clone_into(&mut buf.inner)
191 }
192
193 #[inline]
194 pub fn into_box(&self) -> Box<Slice> {
195 let boxed: Box<[u8]> = self.inner.into();
196 unsafe { mem::transmute(boxed) }
197 }
198
199 pub fn empty_box() -> Box<Slice> {
200 let boxed: Box<[u8]> = Default::default();
201 unsafe { mem::transmute(boxed) }
202 }
203
204 #[inline]
205 pub fn into_arc(&self) -> Arc<Slice> {
206 let arc: Arc<[u8]> = Arc::from(&self.inner);
207 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
208 }
209
210 #[inline]
211 pub fn into_rc(&self) -> Rc<Slice> {
212 let rc: Rc<[u8]> = Rc::from(&self.inner);
213 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
214 }
215
216 #[inline]
217 pub fn make_ascii_lowercase(&mut self) {
218 self.inner.make_ascii_lowercase()
219 }
220
221 #[inline]
222 pub fn make_ascii_uppercase(&mut self) {
223 self.inner.make_ascii_uppercase()
224 }
225
226 #[inline]
227 pub fn to_ascii_lowercase(&self) -> Buf {
228 Buf { inner: self.inner.to_ascii_lowercase() }
229 }
230
231 #[inline]
232 pub fn to_ascii_uppercase(&self) -> Buf {
233 Buf { inner: self.inner.to_ascii_uppercase() }
234 }
235
236 #[inline]
237 pub fn is_ascii(&self) -> bool {
238 self.inner.is_ascii()
239 }
240
241 #[inline]
242 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
243 self.inner.eq_ignore_ascii_case(&other.inner)
244 }
245 }
246
247 /// Platform-specific extensions to [`OsString`].
248 ///
249 /// This trait is sealed: it cannot be implemented outside the standard library.
250 /// This is so that future additional methods are not breaking changes.
251 #[stable(feature = "rust1", since = "1.0.0")]
252 pub trait OsStringExt: Sealed {
253 /// Creates an [`OsString`] from a byte vector.
254 ///
255 /// See the module documentation for an example.
256 #[stable(feature = "rust1", since = "1.0.0")]
257 fn from_vec(vec: Vec<u8>) -> Self;
258
259 /// Yields the underlying byte vector of this [`OsString`].
260 ///
261 /// See the module documentation for an example.
262 #[stable(feature = "rust1", since = "1.0.0")]
263 fn into_vec(self) -> Vec<u8>;
264 }
265
266 #[stable(feature = "rust1", since = "1.0.0")]
267 impl OsStringExt for OsString {
268 fn from_vec(vec: Vec<u8>) -> OsString {
269 FromInner::from_inner(Buf { inner: vec })
270 }
271 fn into_vec(self) -> Vec<u8> {
272 self.into_inner().inner
273 }
274 }
275
276 /// Platform-specific extensions to [`OsStr`].
277 ///
278 /// This trait is sealed: it cannot be implemented outside the standard library.
279 /// This is so that future additional methods are not breaking changes.
280 #[stable(feature = "rust1", since = "1.0.0")]
281 pub trait OsStrExt: Sealed {
282 #[stable(feature = "rust1", since = "1.0.0")]
283 /// Creates an [`OsStr`] from a byte slice.
284 ///
285 /// See the module documentation for an example.
286 fn from_bytes(slice: &[u8]) -> &Self;
287
288 /// Gets the underlying byte view of the [`OsStr`] slice.
289 ///
290 /// See the module documentation for an example.
291 #[stable(feature = "rust1", since = "1.0.0")]
292 fn as_bytes(&self) -> &[u8];
293 }
294
295 #[stable(feature = "rust1", since = "1.0.0")]
296 impl OsStrExt for OsStr {
297 #[inline]
298 fn from_bytes(slice: &[u8]) -> &OsStr {
299 unsafe { mem::transmute(slice) }
300 }
301 #[inline]
302 fn as_bytes(&self) -> &[u8] {
303 &self.as_inner().inner
304 }
305 }