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 fn fmt_nopad(this: &ByteStr, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 for chunk in this.utf8_chunks() {
177 f.write_str(chunk.valid())?;
178 if !chunk.invalid().is_empty() {
179 f.write_str("\u{FFFD}")?;
180 }
181 }
182 Ok(())
183 }
184
185 let Some(align) = f.align() else {
186 return fmt_nopad(self, f);
187 };
188 let nchars: usize = self
189 .utf8_chunks()
190 .map(|chunk| {
191 chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 }
192 })
193 .sum();
194 let padding = f.width().unwrap_or(0).saturating_sub(nchars);
195 let fill = f.fill();
196 let (lpad, rpad) = match align {
197 fmt::Alignment::Left => (0, padding),
198 fmt::Alignment::Right => (padding, 0),
199 fmt::Alignment::Center => {
200 let half = padding / 2;
201 (half, half + padding % 2)
202 }
203 };
204 for _ in 0..lpad {
205 write!(f, "{fill}")?;
206 }
207 fmt_nopad(self, f)?;
208 for _ in 0..rpad {
209 write!(f, "{fill}")?;
210 }
211
212 Ok(())
213 }
214}
215
216#[unstable(feature = "bstr", issue = "134915")]
217#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
218impl const AsRef<[u8]> for ByteStr {
219 #[inline]
220 fn as_ref(&self) -> &[u8] {
221 &self.0
222 }
223}
224
225#[unstable(feature = "bstr", issue = "134915")]
226#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
227impl const AsRef<ByteStr> for ByteStr {
228 #[inline]
229 fn as_ref(&self) -> &ByteStr {
230 self
231 }
232}
233
234#[unstable(feature = "bstr", issue = "134915")]
237#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
238impl const AsRef<ByteStr> for str {
239 #[inline]
240 fn as_ref(&self) -> &ByteStr {
241 ByteStr::new(self)
242 }
243}
244
245#[unstable(feature = "bstr", issue = "134915")]
246#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
247impl const AsMut<[u8]> for ByteStr {
248 #[inline]
249 fn as_mut(&mut self) -> &mut [u8] {
250 &mut self.0
251 }
252}
253
254#[unstable(feature = "bstr", issue = "134915")]
261#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
262impl const Borrow<[u8]> for ByteStr {
263 #[inline]
264 fn borrow(&self) -> &[u8] {
265 &self.0
266 }
267}
268
269#[unstable(feature = "bstr", issue = "134915")]
272#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
273impl const BorrowMut<[u8]> for ByteStr {
274 #[inline]
275 fn borrow_mut(&mut self) -> &mut [u8] {
276 &mut self.0
277 }
278}
279
280#[unstable(feature = "bstr", issue = "134915")]
281impl<'a> Default for &'a ByteStr {
282 fn default() -> Self {
283 ByteStr::from_bytes(b"")
284 }
285}
286
287#[unstable(feature = "bstr", issue = "134915")]
288impl<'a> Default for &'a mut ByteStr {
289 fn default() -> Self {
290 ByteStr::from_bytes_mut(&mut [])
291 }
292}
293
294#[unstable(feature = "bstr", issue = "134915")]
341#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
342impl<'a> const TryFrom<&'a ByteStr> for &'a str {
343 type Error = crate::str::Utf8Error;
344
345 #[inline]
346 fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
347 crate::str::from_utf8(&s.0)
348 }
349}
350
351#[unstable(feature = "bstr", issue = "134915")]
352#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
353impl<'a> const TryFrom<&'a mut ByteStr> for &'a mut str {
354 type Error = crate::str::Utf8Error;
355
356 #[inline]
357 fn try_from(s: &'a mut ByteStr) -> Result<Self, Self::Error> {
358 crate::str::from_utf8_mut(&mut s.0)
359 }
360}