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