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 #[doc(hidden)]
72 #[unstable(feature = "bstr_internals", issue = "none")]
73 #[inline]
74 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
75 pub const fn from_bytes(slice: &[u8]) -> &Self {
76 unsafe { &*(slice as *const [u8] as *const Self) }
79 }
80
81 #[doc(hidden)]
82 #[unstable(feature = "bstr_internals", issue = "none")]
83 #[inline]
84 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
85 pub const fn from_bytes_mut(slice: &mut [u8]) -> &mut Self {
86 unsafe { &mut *(slice as *mut [u8] as *mut Self) }
89 }
90
91 #[doc(hidden)]
92 #[unstable(feature = "bstr_internals", issue = "none")]
93 #[inline]
94 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
95 pub const fn as_bytes(&self) -> &[u8] {
96 &self.0
97 }
98
99 #[doc(hidden)]
100 #[unstable(feature = "bstr_internals", issue = "none")]
101 #[inline]
102 #[rustc_const_unstable(feature = "bstr_internals", issue = "none")]
103 pub const fn as_bytes_mut(&mut self) -> &mut [u8] {
104 &mut self.0
105 }
106}
107
108#[unstable(feature = "bstr", issue = "134915")]
109#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
110impl const Deref for ByteStr {
111 type Target = [u8];
112
113 #[inline]
114 fn deref(&self) -> &[u8] {
115 &self.0
116 }
117}
118
119#[unstable(feature = "bstr", issue = "134915")]
120#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
121impl const DerefMut for ByteStr {
122 #[inline]
123 fn deref_mut(&mut self) -> &mut [u8] {
124 &mut self.0
125 }
126}
127
128#[unstable(feature = "deref_pure_trait", issue = "87121")]
129unsafe impl DerefPure for ByteStr {}
130
131#[unstable(feature = "bstr", issue = "134915")]
132impl fmt::Debug for ByteStr {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 write!(f, "\"")?;
135 for chunk in self.utf8_chunks() {
136 for c in chunk.valid().chars() {
137 match c {
138 '\0' => write!(f, "\\0")?,
139 '\x01'..='\x7f' => write!(f, "{}", (c as u8).escape_ascii())?,
140 _ => write!(f, "{}", c.escape_debug())?,
141 }
142 }
143 write!(f, "{}", chunk.invalid().escape_ascii())?;
144 }
145 write!(f, "\"")?;
146 Ok(())
147 }
148}
149
150#[unstable(feature = "bstr", issue = "134915")]
151impl fmt::Display for ByteStr {
152 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 fn fmt_nopad(this: &ByteStr, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 for chunk in this.utf8_chunks() {
155 f.write_str(chunk.valid())?;
156 if !chunk.invalid().is_empty() {
157 f.write_str("\u{FFFD}")?;
158 }
159 }
160 Ok(())
161 }
162
163 let Some(align) = f.align() else {
164 return fmt_nopad(self, f);
165 };
166 let nchars: usize = self
167 .utf8_chunks()
168 .map(|chunk| {
169 chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 }
170 })
171 .sum();
172 let padding = f.width().unwrap_or(0).saturating_sub(nchars);
173 let fill = f.fill();
174 let (lpad, rpad) = match align {
175 fmt::Alignment::Left => (0, padding),
176 fmt::Alignment::Right => (padding, 0),
177 fmt::Alignment::Center => {
178 let half = padding / 2;
179 (half, half + padding % 2)
180 }
181 };
182 for _ in 0..lpad {
183 write!(f, "{fill}")?;
184 }
185 fmt_nopad(self, f)?;
186 for _ in 0..rpad {
187 write!(f, "{fill}")?;
188 }
189
190 Ok(())
191 }
192}
193
194#[unstable(feature = "bstr", issue = "134915")]
195#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
196impl const AsRef<[u8]> for ByteStr {
197 #[inline]
198 fn as_ref(&self) -> &[u8] {
199 &self.0
200 }
201}
202
203#[unstable(feature = "bstr", issue = "134915")]
204#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
205impl const AsRef<ByteStr> for ByteStr {
206 #[inline]
207 fn as_ref(&self) -> &ByteStr {
208 self
209 }
210}
211
212#[unstable(feature = "bstr", issue = "134915")]
215#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
216impl const AsRef<ByteStr> for str {
217 #[inline]
218 fn as_ref(&self) -> &ByteStr {
219 ByteStr::new(self)
220 }
221}
222
223#[unstable(feature = "bstr", issue = "134915")]
224#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
225impl const AsMut<[u8]> for ByteStr {
226 #[inline]
227 fn as_mut(&mut self) -> &mut [u8] {
228 &mut self.0
229 }
230}
231
232#[unstable(feature = "bstr", issue = "134915")]
239#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
240impl const Borrow<[u8]> for ByteStr {
241 #[inline]
242 fn borrow(&self) -> &[u8] {
243 &self.0
244 }
245}
246
247#[unstable(feature = "bstr", issue = "134915")]
250#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
251impl const BorrowMut<[u8]> for ByteStr {
252 #[inline]
253 fn borrow_mut(&mut self) -> &mut [u8] {
254 &mut self.0
255 }
256}
257
258#[unstable(feature = "bstr", issue = "134915")]
259impl<'a> Default for &'a ByteStr {
260 fn default() -> Self {
261 ByteStr::from_bytes(b"")
262 }
263}
264
265#[unstable(feature = "bstr", issue = "134915")]
266impl<'a> Default for &'a mut ByteStr {
267 fn default() -> Self {
268 ByteStr::from_bytes_mut(&mut [])
269 }
270}
271
272#[unstable(feature = "bstr", issue = "134915")]
319#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
320impl<'a> const TryFrom<&'a ByteStr> for &'a str {
321 type Error = crate::str::Utf8Error;
322
323 #[inline]
324 fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
325 crate::str::from_utf8(&s.0)
326 }
327}
328
329#[unstable(feature = "bstr", issue = "134915")]
330#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
331impl<'a> const TryFrom<&'a mut ByteStr> for &'a mut str {
332 type Error = crate::str::Utf8Error;
333
334 #[inline]
335 fn try_from(s: &'a mut ByteStr) -> Result<Self, Self::Error> {
336 crate::str::from_utf8_mut(&mut s.0)
337 }
338}