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