]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys/unix/os_str.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / library / std / src / sys / unix / os_str.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::collections::TryReserveError;
6 use crate::fmt;
7 use crate::fmt::Write;
8 use crate::mem;
9 use crate::rc::Rc;
10 use crate::str;
11 use crate::sync::Arc;
12 use crate::sys_common::{AsInner, IntoInner};
13
14 use core::str::Utf8Chunks;
15
16 #[cfg(test)]
17 #[path = "../unix/os_str/tests.rs"]
18 mod tests;
19
20 #[derive(Hash)]
21 #[repr(transparent)]
22 pub struct Buf {
23 pub inner: Vec<u8>,
24 }
25
26 #[repr(transparent)]
27 pub struct Slice {
28 pub inner: [u8],
29 }
30
31 impl fmt::Debug for Slice {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 fmt::Debug::fmt(&Utf8Chunks::new(&self.inner).debug(), f)
34 }
35 }
36
37 impl fmt::Display for Slice {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 // If we're the empty string then our iterator won't actually yield
40 // anything, so perform the formatting manually
41 if self.inner.is_empty() {
42 return "".fmt(f);
43 }
44
45 for chunk in Utf8Chunks::new(&self.inner) {
46 let valid = chunk.valid();
47 // If we successfully decoded the whole chunk as a valid string then
48 // we can return a direct formatting of the string which will also
49 // respect various formatting flags if possible.
50 if chunk.invalid().is_empty() {
51 return valid.fmt(f);
52 }
53
54 f.write_str(valid)?;
55 f.write_char(char::REPLACEMENT_CHARACTER)?;
56 }
57 Ok(())
58 }
59 }
60
61 impl fmt::Debug for Buf {
62 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
63 fmt::Debug::fmt(self.as_slice(), formatter)
64 }
65 }
66
67 impl fmt::Display for Buf {
68 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
69 fmt::Display::fmt(self.as_slice(), formatter)
70 }
71 }
72
73 impl Clone for Buf {
74 #[inline]
75 fn clone(&self) -> Self {
76 Buf { inner: self.inner.clone() }
77 }
78
79 #[inline]
80 fn clone_from(&mut self, source: &Self) {
81 self.inner.clone_from(&source.inner)
82 }
83 }
84
85 impl IntoInner<Vec<u8>> for Buf {
86 fn into_inner(self) -> Vec<u8> {
87 self.inner
88 }
89 }
90
91 impl AsInner<[u8]> for Buf {
92 #[inline]
93 fn as_inner(&self) -> &[u8] {
94 &self.inner
95 }
96 }
97
98 impl Buf {
99 #[inline]
100 pub fn into_encoded_bytes(self) -> Vec<u8> {
101 self.inner
102 }
103
104 #[inline]
105 pub unsafe fn from_encoded_bytes_unchecked(s: Vec<u8>) -> Self {
106 Self { inner: s }
107 }
108
109 pub fn from_string(s: String) -> Buf {
110 Buf { inner: s.into_bytes() }
111 }
112
113 #[inline]
114 pub fn with_capacity(capacity: usize) -> Buf {
115 Buf { inner: Vec::with_capacity(capacity) }
116 }
117
118 #[inline]
119 pub fn clear(&mut self) {
120 self.inner.clear()
121 }
122
123 #[inline]
124 pub fn capacity(&self) -> usize {
125 self.inner.capacity()
126 }
127
128 #[inline]
129 pub fn reserve(&mut self, additional: usize) {
130 self.inner.reserve(additional)
131 }
132
133 #[inline]
134 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
135 self.inner.try_reserve(additional)
136 }
137
138 #[inline]
139 pub fn reserve_exact(&mut self, additional: usize) {
140 self.inner.reserve_exact(additional)
141 }
142
143 #[inline]
144 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
145 self.inner.try_reserve_exact(additional)
146 }
147
148 #[inline]
149 pub fn shrink_to_fit(&mut self) {
150 self.inner.shrink_to_fit()
151 }
152
153 #[inline]
154 pub fn shrink_to(&mut self, min_capacity: usize) {
155 self.inner.shrink_to(min_capacity)
156 }
157
158 #[inline]
159 pub fn as_slice(&self) -> &Slice {
160 // SAFETY: Slice just wraps [u8],
161 // and &*self.inner is &[u8], therefore
162 // transmuting &[u8] to &Slice is safe.
163 unsafe { mem::transmute(&*self.inner) }
164 }
165
166 #[inline]
167 pub fn as_mut_slice(&mut self) -> &mut Slice {
168 // SAFETY: Slice just wraps [u8],
169 // and &mut *self.inner is &mut [u8], therefore
170 // transmuting &mut [u8] to &mut Slice is safe.
171 unsafe { mem::transmute(&mut *self.inner) }
172 }
173
174 pub fn into_string(self) -> Result<String, Buf> {
175 String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
176 }
177
178 pub fn push_slice(&mut self, s: &Slice) {
179 self.inner.extend_from_slice(&s.inner)
180 }
181
182 #[inline]
183 pub fn into_box(self) -> Box<Slice> {
184 unsafe { mem::transmute(self.inner.into_boxed_slice()) }
185 }
186
187 #[inline]
188 pub fn from_box(boxed: Box<Slice>) -> Buf {
189 let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
190 Buf { inner: inner.into_vec() }
191 }
192
193 #[inline]
194 pub fn into_arc(&self) -> Arc<Slice> {
195 self.as_slice().into_arc()
196 }
197
198 #[inline]
199 pub fn into_rc(&self) -> Rc<Slice> {
200 self.as_slice().into_rc()
201 }
202 }
203
204 impl Slice {
205 #[inline]
206 pub fn as_encoded_bytes(&self) -> &[u8] {
207 &self.inner
208 }
209
210 #[inline]
211 pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice {
212 unsafe { mem::transmute(s) }
213 }
214
215 #[inline]
216 pub fn from_str(s: &str) -> &Slice {
217 unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
218 }
219
220 pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
221 str::from_utf8(&self.inner)
222 }
223
224 pub fn to_string_lossy(&self) -> Cow<'_, str> {
225 String::from_utf8_lossy(&self.inner)
226 }
227
228 pub fn to_owned(&self) -> Buf {
229 Buf { inner: self.inner.to_vec() }
230 }
231
232 pub fn clone_into(&self, buf: &mut Buf) {
233 self.inner.clone_into(&mut buf.inner)
234 }
235
236 #[inline]
237 pub fn into_box(&self) -> Box<Slice> {
238 let boxed: Box<[u8]> = self.inner.into();
239 unsafe { mem::transmute(boxed) }
240 }
241
242 pub fn empty_box() -> Box<Slice> {
243 let boxed: Box<[u8]> = Default::default();
244 unsafe { mem::transmute(boxed) }
245 }
246
247 #[inline]
248 pub fn into_arc(&self) -> Arc<Slice> {
249 let arc: Arc<[u8]> = Arc::from(&self.inner);
250 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
251 }
252
253 #[inline]
254 pub fn into_rc(&self) -> Rc<Slice> {
255 let rc: Rc<[u8]> = Rc::from(&self.inner);
256 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
257 }
258
259 #[inline]
260 pub fn make_ascii_lowercase(&mut self) {
261 self.inner.make_ascii_lowercase()
262 }
263
264 #[inline]
265 pub fn make_ascii_uppercase(&mut self) {
266 self.inner.make_ascii_uppercase()
267 }
268
269 #[inline]
270 pub fn to_ascii_lowercase(&self) -> Buf {
271 Buf { inner: self.inner.to_ascii_lowercase() }
272 }
273
274 #[inline]
275 pub fn to_ascii_uppercase(&self) -> Buf {
276 Buf { inner: self.inner.to_ascii_uppercase() }
277 }
278
279 #[inline]
280 pub fn is_ascii(&self) -> bool {
281 self.inner.is_ascii()
282 }
283
284 #[inline]
285 pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
286 self.inner.eq_ignore_ascii_case(&other.inner)
287 }
288 }