1mod traits;
4
5#[unstable(feature = "bstr_internals", issue = "none")]
6pub use traits::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord};
7
8use crate::borrow::{Borrow, BorrowMut};
9use crate::fmt;
10use crate::ops::{Deref, DerefMut, DerefPure};
11
12#[unstable(feature = "bstr", issue = "134915")]
41#[repr(transparent)]
42#[doc(alias = "BStr")]
43pub struct ByteStr(pub [u8]);
44
45impl ByteStr {
46 #[inline]
65 #[unstable(feature = "bstr", issue = "134915")]
66 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
67 pub const fn new<B: ?Sized + [const] AsRef<[u8]>>(bytes: &B) -> &Self {
68 ByteStr::from_bytes(bytes.as_ref())
69 }
70
71 #[inline]
77 #[unstable(feature = "bstr", issue = "134915")]
79 pub const fn as_byte_str(&self) -> &ByteStr {
80 self
81 }
82
83 #[inline]
89 #[unstable(feature = "bstr", issue = "134915")]
91 pub const fn as_mut_byte_str(&mut self) -> &mut ByteStr {
92 self
93 }
94
95 #[doc(hidden)]
96 #[unstable(feature = "bstr_internals", issue = "none")]
97 #[inline]
98 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
99 pub const fn from_bytes(slice: &[u8]) -> &Self {
100 unsafe { &*(slice as *const [u8] as *const Self) }
103 }
104
105 #[doc(hidden)]
106 #[unstable(feature = "bstr_internals", issue = "none")]
107 #[inline]
108 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
109 pub const fn from_bytes_mut(slice: &mut [u8]) -> &mut Self {
110 unsafe { &mut *(slice as *mut [u8] as *mut Self) }
113 }
114
115 #[doc(hidden)]
116 #[unstable(feature = "bstr_internals", issue = "none")]
117 #[inline]
118 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
119 pub const fn as_bytes(&self) -> &[u8] {
120 &self.0
121 }
122
123 #[doc(hidden)]
124 #[unstable(feature = "bstr_internals", issue = "none")]
125 #[inline]
126 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
127 pub const fn as_bytes_mut(&mut self) -> &mut [u8] {
128 &mut self.0
129 }
130}
131
132#[unstable(feature = "bstr", issue = "134915")]
133#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
134impl const Deref for ByteStr {
135 type Target = [u8];
136
137 #[inline]
138 fn deref(&self) -> &[u8] {
139 &self.0
140 }
141}
142
143#[unstable(feature = "bstr", issue = "134915")]
144#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
145impl const DerefMut for ByteStr {
146 #[inline]
147 fn deref_mut(&mut self) -> &mut [u8] {
148 &mut self.0
149 }
150}
151
152#[unstable(feature = "deref_pure_trait", issue = "87121")]
153unsafe impl DerefPure for ByteStr {}
154
155#[unstable(feature = "bstr", issue = "134915")]
156impl fmt::Debug for ByteStr {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 write!(f, "\"")?;
159 for chunk in self.utf8_chunks() {
160 for c in chunk.valid().chars() {
161 match c {
162 '\0' => write!(f, "\\0")?,
163 '\x01'..='\x7f' => write!(f, "{}", (c as u8).escape_ascii())?,
164 _ => write!(f, "{}", c.escape_debug())?,
165 }
166 }
167 write!(f, "{}", chunk.invalid().escape_ascii())?;
168 }
169 write!(f, "\"")?;
170 Ok(())
171 }
172}
173
174#[unstable(feature = "bstr", issue = "134915")]
175impl fmt::Display for ByteStr {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 let nchars: usize = self
178 .utf8_chunks()
179 .map(|chunk| {
180 chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 }
181 })
182 .sum();
183
184 let padding = f.width().unwrap_or(0).saturating_sub(nchars);
185 let fill = f.fill();
186
187 let (lpad, rpad) = match f.align() {
188 Some(fmt::Alignment::Right) => (padding, 0),
189 Some(fmt::Alignment::Center) => {
190 let half = padding / 2;
191 (half, half + padding % 2)
192 }
193 _ => (0, padding),
196 };
197
198 for _ in 0..lpad {
199 write!(f, "{fill}")?;
200 }
201
202 for chunk in self.utf8_chunks() {
203 f.write_str(chunk.valid())?;
204 if !chunk.invalid().is_empty() {
205 f.write_str("\u{FFFD}")?;
206 }
207 }
208
209 for _ in 0..rpad {
210 write!(f, "{fill}")?;
211 }
212
213 Ok(())
214 }
215}
216
217#[unstable(feature = "bstr", issue = "134915")]
218#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
219impl const AsRef<[u8]> for ByteStr {
220 #[inline]
221 fn as_ref(&self) -> &[u8] {
222 &self.0
223 }
224}
225
226#[unstable(feature = "bstr", issue = "134915")]
227#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
228impl const AsRef<ByteStr> for ByteStr {
229 #[inline]
230 fn as_ref(&self) -> &ByteStr {
231 self
232 }
233}
234
235#[unstable(feature = "bstr", issue = "134915")]
238#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
239impl const AsRef<ByteStr> for str {
240 #[inline]
241 fn as_ref(&self) -> &ByteStr {
242 ByteStr::new(self)
243 }
244}
245
246#[unstable(feature = "bstr", issue = "134915")]
247#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
248impl const AsMut<[u8]> for ByteStr {
249 #[inline]
250 fn as_mut(&mut self) -> &mut [u8] {
251 &mut self.0
252 }
253}
254
255#[unstable(feature = "bstr", issue = "134915")]
262#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
263impl const Borrow<[u8]> for ByteStr {
264 #[inline]
265 fn borrow(&self) -> &[u8] {
266 &self.0
267 }
268}
269
270#[unstable(feature = "bstr", issue = "134915")]
273#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
274impl const BorrowMut<[u8]> for ByteStr {
275 #[inline]
276 fn borrow_mut(&mut self) -> &mut [u8] {
277 &mut self.0
278 }
279}
280
281#[unstable(feature = "bstr", issue = "134915")]
282impl<'a> Default for &'a ByteStr {
283 fn default() -> Self {
284 ByteStr::from_bytes(b"")
285 }
286}
287
288#[unstable(feature = "bstr", issue = "134915")]
289impl<'a> Default for &'a mut ByteStr {
290 fn default() -> Self {
291 ByteStr::from_bytes_mut(&mut [])
292 }
293}
294
295#[unstable(feature = "bstr", issue = "134915")]
342#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
343impl<'a> const TryFrom<&'a ByteStr> for &'a str {
344 type Error = crate::str::Utf8Error;
345
346 #[inline]
347 fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
348 crate::str::from_utf8(&s.0)
349 }
350}
351
352#[unstable(feature = "bstr", issue = "134915")]
353#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
354impl<'a> const TryFrom<&'a mut ByteStr> for &'a mut str {
355 type Error = crate::str::Utf8Error;
356
357 #[inline]
358 fn try_from(s: &'a mut ByteStr) -> Result<Self, Self::Error> {
359 crate::str::from_utf8_mut(&mut s.0)
360 }
361}