]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/unix/os_str.rs
Rollup merge of #90704 - ijackson:exitstatus-comments, r=joshtriplett
[rust.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::fmt;
6 use crate::fmt::Write;
7 use crate::mem;
8 use crate::rc::Rc;
9 use crate::str;
10 use crate::sync::Arc;
11 use crate::sys_common::{AsInner, IntoInner};
12
13 use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
14
15 #[cfg(test)]
16 #[path = "../unix/os_str/tests.rs"]
17 mod tests;
18
19 #[derive(Hash)]
20 #[repr(transparent)]
21 pub struct Buf {
22     pub inner: Vec<u8>,
23 }
24
25 #[repr(transparent)]
26 pub struct Slice {
27     pub inner: [u8],
28 }
29
30 impl fmt::Debug for Slice {
31     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32         // Writes out a valid unicode string with the correct escape sequences
33
34         formatter.write_str("\"")?;
35         for Utf8LossyChunk { valid, broken } in Utf8Lossy::from_bytes(&self.inner).chunks() {
36             for c in valid.chars().flat_map(|c| c.escape_debug()) {
37                 formatter.write_char(c)?
38             }
39
40             for b in broken {
41                 write!(formatter, "\\x{:02X}", b)?;
42             }
43         }
44         formatter.write_str("\"")
45     }
46 }
47
48 impl fmt::Display for Slice {
49     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50         fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
51     }
52 }
53
54 impl fmt::Debug for Buf {
55     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56         fmt::Debug::fmt(self.as_slice(), formatter)
57     }
58 }
59
60 impl fmt::Display for Buf {
61     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62         fmt::Display::fmt(self.as_slice(), formatter)
63     }
64 }
65
66 impl Clone for Buf {
67     #[inline]
68     fn clone(&self) -> Self {
69         Buf { inner: self.inner.clone() }
70     }
71
72     #[inline]
73     fn clone_from(&mut self, source: &Self) {
74         self.inner.clone_from(&source.inner)
75     }
76 }
77
78 impl IntoInner<Vec<u8>> for Buf {
79     fn into_inner(self) -> Vec<u8> {
80         self.inner
81     }
82 }
83
84 impl AsInner<[u8]> for Buf {
85     fn as_inner(&self) -> &[u8] {
86         &self.inner
87     }
88 }
89
90 impl Buf {
91     pub fn from_string(s: String) -> Buf {
92         Buf { inner: s.into_bytes() }
93     }
94
95     #[inline]
96     pub fn with_capacity(capacity: usize) -> Buf {
97         Buf { inner: Vec::with_capacity(capacity) }
98     }
99
100     #[inline]
101     pub fn clear(&mut self) {
102         self.inner.clear()
103     }
104
105     #[inline]
106     pub fn capacity(&self) -> usize {
107         self.inner.capacity()
108     }
109
110     #[inline]
111     pub fn reserve(&mut self, additional: usize) {
112         self.inner.reserve(additional)
113     }
114
115     #[inline]
116     pub fn reserve_exact(&mut self, additional: usize) {
117         self.inner.reserve_exact(additional)
118     }
119
120     #[inline]
121     pub fn shrink_to_fit(&mut self) {
122         self.inner.shrink_to_fit()
123     }
124
125     #[inline]
126     pub fn shrink_to(&mut self, min_capacity: usize) {
127         self.inner.shrink_to(min_capacity)
128     }
129
130     #[inline]
131     pub fn as_slice(&self) -> &Slice {
132         // SAFETY: Slice just wraps [u8],
133         // and &*self.inner is &[u8], therefore
134         // transmuting &[u8] to &Slice is safe.
135         unsafe { mem::transmute(&*self.inner) }
136     }
137
138     #[inline]
139     pub fn as_mut_slice(&mut self) -> &mut Slice {
140         // SAFETY: Slice just wraps [u8],
141         // and &mut *self.inner is &mut [u8], therefore
142         // transmuting &mut [u8] to &mut Slice is safe.
143         unsafe { mem::transmute(&mut *self.inner) }
144     }
145
146     pub fn into_string(self) -> Result<String, Buf> {
147         String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
148     }
149
150     pub fn push_slice(&mut self, s: &Slice) {
151         self.inner.extend_from_slice(&s.inner)
152     }
153
154     #[inline]
155     pub fn into_box(self) -> Box<Slice> {
156         unsafe { mem::transmute(self.inner.into_boxed_slice()) }
157     }
158
159     #[inline]
160     pub fn from_box(boxed: Box<Slice>) -> Buf {
161         let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
162         Buf { inner: inner.into_vec() }
163     }
164
165     #[inline]
166     pub fn into_arc(&self) -> Arc<Slice> {
167         self.as_slice().into_arc()
168     }
169
170     #[inline]
171     pub fn into_rc(&self) -> Rc<Slice> {
172         self.as_slice().into_rc()
173     }
174 }
175
176 impl Slice {
177     #[inline]
178     fn from_u8_slice(s: &[u8]) -> &Slice {
179         unsafe { mem::transmute(s) }
180     }
181
182     #[inline]
183     pub fn from_str(s: &str) -> &Slice {
184         Slice::from_u8_slice(s.as_bytes())
185     }
186
187     pub fn to_str(&self) -> Option<&str> {
188         str::from_utf8(&self.inner).ok()
189     }
190
191     pub fn to_string_lossy(&self) -> Cow<'_, str> {
192         String::from_utf8_lossy(&self.inner)
193     }
194
195     pub fn to_owned(&self) -> Buf {
196         Buf { inner: self.inner.to_vec() }
197     }
198
199     pub fn clone_into(&self, buf: &mut Buf) {
200         self.inner.clone_into(&mut buf.inner)
201     }
202
203     #[inline]
204     pub fn into_box(&self) -> Box<Slice> {
205         let boxed: Box<[u8]> = self.inner.into();
206         unsafe { mem::transmute(boxed) }
207     }
208
209     pub fn empty_box() -> Box<Slice> {
210         let boxed: Box<[u8]> = Default::default();
211         unsafe { mem::transmute(boxed) }
212     }
213
214     #[inline]
215     pub fn into_arc(&self) -> Arc<Slice> {
216         let arc: Arc<[u8]> = Arc::from(&self.inner);
217         unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
218     }
219
220     #[inline]
221     pub fn into_rc(&self) -> Rc<Slice> {
222         let rc: Rc<[u8]> = Rc::from(&self.inner);
223         unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
224     }
225
226     #[inline]
227     pub fn make_ascii_lowercase(&mut self) {
228         self.inner.make_ascii_lowercase()
229     }
230
231     #[inline]
232     pub fn make_ascii_uppercase(&mut self) {
233         self.inner.make_ascii_uppercase()
234     }
235
236     #[inline]
237     pub fn to_ascii_lowercase(&self) -> Buf {
238         Buf { inner: self.inner.to_ascii_lowercase() }
239     }
240
241     #[inline]
242     pub fn to_ascii_uppercase(&self) -> Buf {
243         Buf { inner: self.inner.to_ascii_uppercase() }
244     }
245
246     #[inline]
247     pub fn is_ascii(&self) -> bool {
248         self.inner.is_ascii()
249     }
250
251     #[inline]
252     pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool {
253         self.inner.eq_ignore_ascii_case(&other.inner)
254     }
255 }