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