Coverage Report

Created: 2026-09-06 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bstr-1.12.1/src/impls.rs
Line
Count
Source
1
macro_rules! impl_partial_eq {
2
    ($lhs:ty, $rhs:ty) => {
3
        impl<'a> PartialEq<$rhs> for $lhs {
4
            #[inline]
5
0
            fn eq(&self, other: &$rhs) -> bool {
6
0
                let other: &[u8] = other.as_ref();
7
0
                PartialEq::eq(self.as_bytes(), other)
8
0
            }
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<alloc::string::String>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<alloc::vec::Vec<u8>>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<[u8]>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<&[u8]>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<[u8]>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<alloc::string::String>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<&[u8]>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<str>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<str>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<&str>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<&str>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<alloc::vec::Vec<u8>>>::eq
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<alloc::vec::Vec<u8>>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<alloc::string::String>>::eq
9
        }
10
11
        impl<'a> PartialEq<$lhs> for $rhs {
12
            #[inline]
13
0
            fn eq(&self, other: &$lhs) -> bool {
14
0
                let this: &[u8] = self.as_ref();
15
0
                PartialEq::eq(this, other.as_bytes())
16
0
            }
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <[u8] as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <&[u8] as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <[u8] as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <&[u8] as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <str as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <str as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <&str as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <&str as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
17
        }
18
    };
19
}
20
21
macro_rules! impl_partial_eq_n {
22
    ($lhs:ty, $rhs:ty) => {
23
        impl<'a, const N: usize> PartialEq<$rhs> for $lhs {
24
            #[inline]
25
0
            fn eq(&self, other: &$rhs) -> bool {
26
0
                let other: &[u8] = other.as_ref();
27
0
                PartialEq::eq(self.as_bytes(), other)
28
0
            }
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<[u8; _]>>::eq
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialEq<&[u8; _]>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<[u8; _]>>::eq
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialEq<&[u8; _]>>::eq
29
        }
30
31
        impl<'a, const N: usize> PartialEq<$lhs> for $rhs {
32
            #[inline]
33
0
            fn eq(&self, other: &$lhs) -> bool {
34
0
                let this: &[u8] = self.as_ref();
35
0
                PartialEq::eq(this, other.as_bytes())
36
0
            }
Unexecuted instantiation: <[u8; _] as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <&[u8; _] as core::cmp::PartialEq<bstr::bstr::BStr>>::eq
Unexecuted instantiation: <[u8; _] as core::cmp::PartialEq<bstr::bstring::BString>>::eq
Unexecuted instantiation: <&[u8; _] as core::cmp::PartialEq<bstr::bstring::BString>>::eq
37
        }
38
    };
39
}
40
41
#[cfg(feature = "alloc")]
42
macro_rules! impl_partial_eq_cow {
43
    ($lhs:ty, $rhs:ty) => {
44
        impl<'a> PartialEq<$rhs> for $lhs {
45
            #[inline]
46
0
            fn eq(&self, other: &$rhs) -> bool {
47
0
                let other: &[u8] = (&**other).as_ref();
48
0
                PartialEq::eq(self.as_bytes(), other)
49
0
            }
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<alloc::borrow::Cow<bstr::bstr::BStr>>>::eq
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<alloc::borrow::Cow<str>>>::eq
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialEq<alloc::borrow::Cow<[u8]>>>::eq
50
        }
51
52
        impl<'a> PartialEq<$lhs> for $rhs {
53
            #[inline]
54
0
            fn eq(&self, other: &$lhs) -> bool {
55
0
                let this: &[u8] = (&**self).as_ref();
56
0
                PartialEq::eq(this, other.as_bytes())
57
0
            }
Unexecuted instantiation: <alloc::borrow::Cow<bstr::bstr::BStr> as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::borrow::Cow<str> as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
Unexecuted instantiation: <alloc::borrow::Cow<[u8]> as core::cmp::PartialEq<&bstr::bstr::BStr>>::eq
58
        }
59
    };
60
}
61
62
macro_rules! impl_partial_ord {
63
    ($lhs:ty, $rhs:ty) => {
64
        impl<'a> PartialOrd<$rhs> for $lhs {
65
            #[inline]
66
0
            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
67
0
                let other: &[u8] = other.as_ref();
68
0
                PartialOrd::partial_cmp(self.as_bytes(), other)
69
0
            }
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<&[u8]>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<alloc::string::String>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<str>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<&str>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<[u8]>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<&[u8]>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<&bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<str>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<&str>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<alloc::vec::Vec<u8>>>::partial_cmp
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialOrd<alloc::vec::Vec<u8>>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<alloc::string::String>>::partial_cmp
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialOrd<alloc::string::String>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<alloc::vec::Vec<u8>>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<[u8]>>::partial_cmp
70
        }
71
72
        impl<'a> PartialOrd<$lhs> for $rhs {
73
            #[inline]
74
0
            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
75
0
                let this: &[u8] = self.as_ref();
76
0
                PartialOrd::partial_cmp(this, other.as_bytes())
77
0
            }
Unexecuted instantiation: <[u8] as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <&[u8] as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <str as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <&str as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <[u8] as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <&[u8] as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <&bstr::bstr::BStr as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <str as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <&str as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialOrd<&bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <alloc::string::String as core::cmp::PartialOrd<&bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <alloc::vec::Vec<u8> as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
78
        }
79
    };
80
}
81
82
macro_rules! impl_partial_ord_n {
83
    ($lhs:ty, $rhs:ty) => {
84
        impl<'a, const N: usize> PartialOrd<$rhs> for $lhs {
85
            #[inline]
86
0
            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
87
0
                let other: &[u8] = other.as_ref();
88
0
                PartialOrd::partial_cmp(self.as_bytes(), other)
89
0
            }
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<[u8; _]>>::partial_cmp
Unexecuted instantiation: <bstr::bstr::BStr as core::cmp::PartialOrd<&[u8; _]>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<[u8; _]>>::partial_cmp
Unexecuted instantiation: <bstr::bstring::BString as core::cmp::PartialOrd<&[u8; _]>>::partial_cmp
90
        }
91
92
        impl<'a, const N: usize> PartialOrd<$lhs> for $rhs {
93
            #[inline]
94
0
            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
95
0
                let this: &[u8] = self.as_ref();
96
0
                PartialOrd::partial_cmp(this, other.as_bytes())
97
0
            }
Unexecuted instantiation: <[u8; _] as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <&[u8; _] as core::cmp::PartialOrd<bstr::bstr::BStr>>::partial_cmp
Unexecuted instantiation: <[u8; _] as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
Unexecuted instantiation: <&[u8; _] as core::cmp::PartialOrd<bstr::bstring::BString>>::partial_cmp
98
        }
99
    };
100
}
101
102
#[cfg(feature = "alloc")]
103
mod bstring {
104
    use core::{cmp::Ordering, fmt, hash, ops, str::FromStr};
105
106
    use alloc::{
107
        borrow::{Borrow, BorrowMut, Cow, ToOwned},
108
        string::String,
109
        vec,
110
        vec::Vec,
111
    };
112
113
    use crate::{
114
        bstr::BStr, bstring::BString, ext_slice::ByteSlice, ext_vec::ByteVec,
115
    };
116
117
    impl fmt::Display for BString {
118
        #[inline]
119
0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120
0
            fmt::Display::fmt(self.as_bstr(), f)
121
0
        }
122
    }
123
124
    impl fmt::Debug for BString {
125
        #[inline]
126
0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127
0
            fmt::Debug::fmt(self.as_bstr(), f)
128
0
        }
129
    }
130
131
    impl FromStr for BString {
132
        type Err = crate::Utf8Error;
133
134
        #[inline]
135
0
        fn from_str(s: &str) -> Result<BString, crate::Utf8Error> {
136
0
            Ok(BString::from(s))
137
0
        }
138
    }
139
140
    impl ops::Deref for BString {
141
        type Target = Vec<u8>;
142
143
        #[inline]
144
72.4M
        fn deref(&self) -> &Vec<u8> {
145
72.4M
            self.as_vec()
146
72.4M
        }
147
    }
148
149
    impl ops::DerefMut for BString {
150
        #[inline]
151
36.2M
        fn deref_mut(&mut self) -> &mut Vec<u8> {
152
36.2M
            self.as_vec_mut()
153
36.2M
        }
154
    }
155
156
    impl AsRef<[u8]> for BString {
157
        #[inline]
158
25.8M
        fn as_ref(&self) -> &[u8] {
159
25.8M
            self.as_bytes()
160
25.8M
        }
161
    }
162
163
    impl AsRef<BStr> for BString {
164
        #[inline]
165
0
        fn as_ref(&self) -> &BStr {
166
0
            self.as_bstr()
167
0
        }
168
    }
169
170
    impl AsMut<[u8]> for BString {
171
        #[inline]
172
0
        fn as_mut(&mut self) -> &mut [u8] {
173
0
            self.as_bytes_mut()
174
0
        }
175
    }
176
177
    impl AsMut<BStr> for BString {
178
        #[inline]
179
0
        fn as_mut(&mut self) -> &mut BStr {
180
0
            self.as_mut_bstr()
181
0
        }
182
    }
183
184
    impl Borrow<[u8]> for BString {
185
        #[inline]
186
0
        fn borrow(&self) -> &[u8] {
187
0
            self.as_bytes()
188
0
        }
189
    }
190
191
    impl Borrow<BStr> for BString {
192
        #[inline]
193
0
        fn borrow(&self) -> &BStr {
194
0
            self.as_bstr()
195
0
        }
196
    }
197
198
    impl Borrow<BStr> for Vec<u8> {
199
        #[inline]
200
0
        fn borrow(&self) -> &BStr {
201
0
            self.as_slice().as_bstr()
202
0
        }
203
    }
204
205
    impl Borrow<BStr> for String {
206
        #[inline]
207
0
        fn borrow(&self) -> &BStr {
208
0
            self.as_bytes().as_bstr()
209
0
        }
210
    }
211
212
    impl BorrowMut<[u8]> for BString {
213
        #[inline]
214
0
        fn borrow_mut(&mut self) -> &mut [u8] {
215
0
            self.as_bytes_mut()
216
0
        }
217
    }
218
219
    impl BorrowMut<BStr> for BString {
220
        #[inline]
221
0
        fn borrow_mut(&mut self) -> &mut BStr {
222
0
            self.as_mut_bstr()
223
0
        }
224
    }
225
226
    impl BorrowMut<BStr> for Vec<u8> {
227
        #[inline]
228
0
        fn borrow_mut(&mut self) -> &mut BStr {
229
0
            BStr::new_mut(self.as_mut_slice())
230
0
        }
231
    }
232
233
    impl ToOwned for BStr {
234
        type Owned = BString;
235
236
        #[inline]
237
0
        fn to_owned(&self) -> BString {
238
0
            BString::from(self)
239
0
        }
240
    }
241
242
    impl Default for BString {
243
0
        fn default() -> BString {
244
0
            BString::from(vec![])
245
0
        }
246
    }
247
248
    impl<'a, const N: usize> From<&'a [u8; N]> for BString {
249
        #[inline]
250
0
        fn from(s: &'a [u8; N]) -> BString {
251
0
            BString::from(&s[..])
252
0
        }
253
    }
254
255
    impl<const N: usize> From<[u8; N]> for BString {
256
        #[inline]
257
0
        fn from(s: [u8; N]) -> BString {
258
0
            BString::from(&s[..])
259
0
        }
260
    }
261
262
    impl<'a> From<&'a [u8]> for BString {
263
        #[inline]
264
4.64M
        fn from(s: &'a [u8]) -> BString {
265
4.64M
            BString::from(s.to_vec())
266
4.64M
        }
267
    }
268
269
    impl From<Vec<u8>> for BString {
270
        #[inline]
271
26.7M
        fn from(s: Vec<u8>) -> BString {
272
26.7M
            BString::new(s)
273
26.7M
        }
274
    }
275
276
    impl From<BString> for Vec<u8> {
277
        #[inline]
278
0
        fn from(s: BString) -> Vec<u8> {
279
0
            s.into_vec()
280
0
        }
281
    }
282
283
    impl<'a> From<&'a str> for BString {
284
        #[inline]
285
0
        fn from(s: &'a str) -> BString {
286
0
            BString::from(s.as_bytes().to_vec())
287
0
        }
288
    }
289
290
    impl From<String> for BString {
291
        #[inline]
292
0
        fn from(s: String) -> BString {
293
0
            BString::from(s.into_bytes())
294
0
        }
295
    }
296
297
    impl<'a> From<&'a BStr> for BString {
298
        #[inline]
299
0
        fn from(s: &'a BStr) -> BString {
300
0
            BString::from(s.bytes.to_vec())
301
0
        }
302
    }
303
304
    impl<'a> From<BString> for Cow<'a, BStr> {
305
        #[inline]
306
0
        fn from(s: BString) -> Cow<'a, BStr> {
307
0
            Cow::Owned(s)
308
0
        }
309
    }
310
311
    impl<'a> From<&'a BString> for Cow<'a, BStr> {
312
        #[inline]
313
0
        fn from(s: &'a BString) -> Cow<'a, BStr> {
314
0
            Cow::Borrowed(s.as_bstr())
315
0
        }
316
    }
317
318
    impl TryFrom<BString> for String {
319
        type Error = crate::FromUtf8Error;
320
321
        #[inline]
322
0
        fn try_from(s: BString) -> Result<String, crate::FromUtf8Error> {
323
0
            s.into_vec().into_string()
324
0
        }
325
    }
326
327
    impl<'a> TryFrom<&'a BString> for &'a str {
328
        type Error = crate::Utf8Error;
329
330
        #[inline]
331
0
        fn try_from(s: &'a BString) -> Result<&'a str, crate::Utf8Error> {
332
0
            s.as_bytes().to_str()
333
0
        }
334
    }
335
336
    impl FromIterator<char> for BString {
337
        #[inline]
338
0
        fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString {
339
0
            BString::from(iter.into_iter().collect::<String>())
340
0
        }
341
    }
342
343
    impl FromIterator<u8> for BString {
344
        #[inline]
345
0
        fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString {
346
0
            BString::from(iter.into_iter().collect::<Vec<u8>>())
347
0
        }
348
    }
349
350
    impl<'a> FromIterator<&'a str> for BString {
351
        #[inline]
352
0
        fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString {
353
0
            let mut buf = vec![];
354
0
            for b in iter {
355
0
                buf.push_str(b);
356
0
            }
357
0
            BString::from(buf)
358
0
        }
359
    }
360
361
    impl<'a> FromIterator<&'a [u8]> for BString {
362
        #[inline]
363
0
        fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString {
364
0
            let mut buf = vec![];
365
0
            for b in iter {
366
0
                buf.push_str(b);
367
0
            }
368
0
            BString::from(buf)
369
0
        }
370
    }
371
372
    impl<'a> FromIterator<&'a BStr> for BString {
373
        #[inline]
374
0
        fn from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString {
375
0
            let mut buf = vec![];
376
0
            for b in iter {
377
0
                buf.push_str(b);
378
0
            }
379
0
            BString::from(buf)
380
0
        }
381
    }
382
383
    impl FromIterator<BString> for BString {
384
        #[inline]
385
0
        fn from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString {
386
0
            let mut buf = vec![];
387
0
            for b in iter {
388
0
                buf.push_str(b);
389
0
            }
390
0
            BString::from(buf)
391
0
        }
392
    }
393
394
    impl Eq for BString {}
395
396
    impl PartialEq for BString {
397
        #[inline]
398
0
        fn eq(&self, other: &BString) -> bool {
399
0
            self[..] == other[..]
400
0
        }
401
    }
402
403
    impl_partial_eq!(BString, Vec<u8>);
404
    impl_partial_eq!(BString, [u8]);
405
    impl_partial_eq!(BString, &'a [u8]);
406
    impl_partial_eq!(BString, String);
407
    impl_partial_eq!(BString, str);
408
    impl_partial_eq!(BString, &'a str);
409
    impl_partial_eq!(BString, BStr);
410
    impl_partial_eq!(BString, &'a BStr);
411
    impl_partial_eq_n!(BString, [u8; N]);
412
    impl_partial_eq_n!(BString, &'a [u8; N]);
413
414
    impl hash::Hash for BString {
415
        #[inline]
416
0
        fn hash<H: hash::Hasher>(&self, state: &mut H) {
417
0
            self.as_bytes().hash(state);
418
0
        }
419
    }
420
421
    impl PartialOrd for BString {
422
        #[inline]
423
0
        fn partial_cmp(&self, other: &BString) -> Option<Ordering> {
424
0
            PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
425
0
        }
426
    }
427
428
    impl Ord for BString {
429
        #[inline]
430
0
        fn cmp(&self, other: &BString) -> Ordering {
431
0
            self.partial_cmp(other).unwrap()
432
0
        }
433
    }
434
435
    impl_partial_ord!(BString, Vec<u8>);
436
    impl_partial_ord!(BString, [u8]);
437
    impl_partial_ord!(BString, &'a [u8]);
438
    impl_partial_ord!(BString, String);
439
    impl_partial_ord!(BString, str);
440
    impl_partial_ord!(BString, &'a str);
441
    impl_partial_ord!(BString, BStr);
442
    impl_partial_ord!(BString, &'a BStr);
443
    impl_partial_ord_n!(BString, [u8; N]);
444
    impl_partial_ord_n!(BString, &'a [u8; N]);
445
}
446
447
mod bstr {
448
    use core::{
449
        borrow::{Borrow, BorrowMut},
450
        cmp::Ordering,
451
        fmt, hash, ops,
452
    };
453
454
    #[cfg(feature = "alloc")]
455
    use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
456
457
    use crate::{bstr::BStr, ext_slice::ByteSlice};
458
459
    impl fmt::Display for BStr {
460
        #[inline]
461
0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
462
            /// Write the given bstr (lossily) to the given formatter.
463
0
            fn write_bstr(
464
0
                f: &mut fmt::Formatter<'_>,
465
0
                bstr: &BStr,
466
0
            ) -> Result<(), fmt::Error> {
467
0
                for chunk in bstr.utf8_chunks() {
468
0
                    f.write_str(chunk.valid())?;
469
0
                    if !chunk.invalid().is_empty() {
470
0
                        f.write_str("\u{FFFD}")?;
471
0
                    }
472
                }
473
0
                Ok(())
474
0
            }
475
476
            /// Write 'num' fill characters to the given formatter.
477
0
            fn write_pads(
478
0
                f: &mut fmt::Formatter<'_>,
479
0
                num: usize,
480
0
            ) -> fmt::Result {
481
0
                let fill = f.fill();
482
0
                for _ in 0..num {
483
0
                    f.write_fmt(format_args!("{}", fill))?;
484
                }
485
0
                Ok(())
486
0
            }
487
488
0
            if let Some(align) = f.align() {
489
0
                let width = f.width().unwrap_or(0);
490
0
                let nchars = self.chars().count();
491
0
                let remaining_pads = width.saturating_sub(nchars);
492
0
                match align {
493
                    fmt::Alignment::Left => {
494
0
                        write_bstr(f, self)?;
495
0
                        write_pads(f, remaining_pads)?;
496
                    }
497
                    fmt::Alignment::Right => {
498
0
                        write_pads(f, remaining_pads)?;
499
0
                        write_bstr(f, self)?;
500
                    }
501
                    fmt::Alignment::Center => {
502
0
                        let half = remaining_pads / 2;
503
0
                        let second_half = if remaining_pads % 2 == 0 {
504
0
                            half
505
                        } else {
506
0
                            half + 1
507
                        };
508
0
                        write_pads(f, half)?;
509
0
                        write_bstr(f, self)?;
510
0
                        write_pads(f, second_half)?;
511
                    }
512
                }
513
0
                Ok(())
514
            } else {
515
0
                write_bstr(f, self)?;
516
0
                Ok(())
517
            }
518
0
        }
519
    }
520
521
    impl fmt::Debug for BStr {
522
        #[inline]
523
0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
524
0
            write!(f, "\"")?;
525
0
            for (s, e, ch) in self.char_indices() {
526
0
                match ch {
527
0
                    '\0' => write!(f, "\\0")?,
528
0
                    '\x01'..='\x7f' => {
529
0
                        write!(f, "{}", (ch as u8).escape_ascii())?;
530
                    }
531
                    '\u{FFFD}' => {
532
0
                        let bytes = self[s..e].as_bytes();
533
0
                        if bytes == b"\xEF\xBF\xBD" {
534
0
                            write!(f, "{}", ch.escape_debug())?;
535
                        } else {
536
0
                            for &b in self[s..e].as_bytes() {
537
0
                                write!(f, "\\x{:02x}", b)?;
538
                            }
539
                        }
540
                    }
541
                    _ => {
542
0
                        write!(f, "{}", ch.escape_debug())?;
543
                    }
544
                }
545
            }
546
0
            write!(f, "\"")?;
547
0
            Ok(())
548
0
        }
549
    }
550
551
    impl ops::Deref for BStr {
552
        type Target = [u8];
553
554
        #[inline]
555
0
        fn deref(&self) -> &[u8] {
556
0
            &self.bytes
557
0
        }
558
    }
559
560
    impl ops::DerefMut for BStr {
561
        #[inline]
562
0
        fn deref_mut(&mut self) -> &mut [u8] {
563
0
            &mut self.bytes
564
0
        }
565
    }
566
567
    impl ops::Index<usize> for BStr {
568
        type Output = u8;
569
570
        #[inline]
571
0
        fn index(&self, idx: usize) -> &u8 {
572
0
            &self.as_bytes()[idx]
573
0
        }
574
    }
575
576
    impl ops::Index<ops::RangeFull> for BStr {
577
        type Output = BStr;
578
579
        #[inline]
580
0
        fn index(&self, _: ops::RangeFull) -> &BStr {
581
0
            self
582
0
        }
583
    }
584
585
    impl ops::Index<ops::Range<usize>> for BStr {
586
        type Output = BStr;
587
588
        #[inline]
589
0
        fn index(&self, r: ops::Range<usize>) -> &BStr {
590
0
            BStr::new(&self.as_bytes()[r.start..r.end])
591
0
        }
592
    }
593
594
    impl ops::Index<ops::RangeInclusive<usize>> for BStr {
595
        type Output = BStr;
596
597
        #[inline]
598
0
        fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
599
0
            BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
600
0
        }
601
    }
602
603
    impl ops::Index<ops::RangeFrom<usize>> for BStr {
604
        type Output = BStr;
605
606
        #[inline]
607
0
        fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
608
0
            BStr::new(&self.as_bytes()[r.start..])
609
0
        }
610
    }
611
612
    impl ops::Index<ops::RangeTo<usize>> for BStr {
613
        type Output = BStr;
614
615
        #[inline]
616
0
        fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
617
0
            BStr::new(&self.as_bytes()[..r.end])
618
0
        }
619
    }
620
621
    impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
622
        type Output = BStr;
623
624
        #[inline]
625
0
        fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
626
0
            BStr::new(&self.as_bytes()[..=r.end])
627
0
        }
628
    }
629
630
    impl ops::IndexMut<usize> for BStr {
631
        #[inline]
632
0
        fn index_mut(&mut self, idx: usize) -> &mut u8 {
633
0
            &mut self.bytes[idx]
634
0
        }
635
    }
636
637
    impl ops::IndexMut<ops::RangeFull> for BStr {
638
        #[inline]
639
0
        fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr {
640
0
            self
641
0
        }
642
    }
643
644
    impl ops::IndexMut<ops::Range<usize>> for BStr {
645
        #[inline]
646
0
        fn index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr {
647
0
            BStr::from_bytes_mut(&mut self.bytes[r.start..r.end])
648
0
        }
649
    }
650
651
    impl ops::IndexMut<ops::RangeInclusive<usize>> for BStr {
652
        #[inline]
653
0
        fn index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr {
654
0
            BStr::from_bytes_mut(&mut self.bytes[*r.start()..=*r.end()])
655
0
        }
656
    }
657
658
    impl ops::IndexMut<ops::RangeFrom<usize>> for BStr {
659
        #[inline]
660
0
        fn index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr {
661
0
            BStr::from_bytes_mut(&mut self.bytes[r.start..])
662
0
        }
663
    }
664
665
    impl ops::IndexMut<ops::RangeTo<usize>> for BStr {
666
        #[inline]
667
0
        fn index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr {
668
0
            BStr::from_bytes_mut(&mut self.bytes[..r.end])
669
0
        }
670
    }
671
672
    impl ops::IndexMut<ops::RangeToInclusive<usize>> for BStr {
673
        #[inline]
674
0
        fn index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr {
675
0
            BStr::from_bytes_mut(&mut self.bytes[..=r.end])
676
0
        }
677
    }
678
679
    impl AsRef<[u8]> for BStr {
680
        #[inline]
681
0
        fn as_ref(&self) -> &[u8] {
682
0
            self.as_bytes()
683
0
        }
684
    }
685
686
    impl AsRef<BStr> for BStr {
687
        #[inline]
688
0
        fn as_ref(&self) -> &BStr {
689
0
            self
690
0
        }
691
    }
692
693
    impl AsRef<BStr> for [u8] {
694
        #[inline]
695
0
        fn as_ref(&self) -> &BStr {
696
0
            BStr::new(self)
697
0
        }
698
    }
699
700
    impl AsRef<BStr> for str {
701
        #[inline]
702
0
        fn as_ref(&self) -> &BStr {
703
0
            BStr::new(self)
704
0
        }
705
    }
706
707
    impl AsMut<[u8]> for BStr {
708
        #[inline]
709
0
        fn as_mut(&mut self) -> &mut [u8] {
710
0
            &mut self.bytes
711
0
        }
712
    }
713
714
    impl AsMut<BStr> for [u8] {
715
        #[inline]
716
0
        fn as_mut(&mut self) -> &mut BStr {
717
0
            BStr::new_mut(self)
718
0
        }
719
    }
720
721
    impl Borrow<BStr> for [u8] {
722
        #[inline]
723
0
        fn borrow(&self) -> &BStr {
724
0
            self.as_bstr()
725
0
        }
726
    }
727
728
    impl Borrow<BStr> for str {
729
        #[inline]
730
0
        fn borrow(&self) -> &BStr {
731
0
            self.as_bytes().as_bstr()
732
0
        }
733
    }
734
735
    impl Borrow<[u8]> for BStr {
736
        #[inline]
737
0
        fn borrow(&self) -> &[u8] {
738
0
            self.as_bytes()
739
0
        }
740
    }
741
742
    impl BorrowMut<BStr> for [u8] {
743
        #[inline]
744
0
        fn borrow_mut(&mut self) -> &mut BStr {
745
0
            BStr::new_mut(self)
746
0
        }
747
    }
748
749
    impl BorrowMut<[u8]> for BStr {
750
        #[inline]
751
0
        fn borrow_mut(&mut self) -> &mut [u8] {
752
0
            self.as_bytes_mut()
753
0
        }
754
    }
755
756
    impl<'a> Default for &'a BStr {
757
0
        fn default() -> &'a BStr {
758
0
            BStr::from_bytes(b"")
759
0
        }
760
    }
761
762
    impl<'a> Default for &'a mut BStr {
763
0
        fn default() -> &'a mut BStr {
764
0
            BStr::from_bytes_mut(&mut [])
765
0
        }
766
    }
767
768
    #[cfg(feature = "alloc")]
769
    impl Default for Box<BStr> {
770
        #[inline]
771
0
        fn default() -> Self {
772
0
            BStr::from_boxed_bytes(Box::default())
773
0
        }
774
    }
775
776
    impl<'a, const N: usize> From<&'a [u8; N]> for &'a BStr {
777
        #[inline]
778
0
        fn from(s: &'a [u8; N]) -> &'a BStr {
779
0
            BStr::from_bytes(s)
780
0
        }
781
    }
782
783
    impl<'a> From<&'a [u8]> for &'a BStr {
784
        #[inline]
785
0
        fn from(s: &'a [u8]) -> &'a BStr {
786
0
            BStr::from_bytes(s)
787
0
        }
788
    }
789
790
    impl<'a> From<&'a BStr> for &'a [u8] {
791
        #[inline]
792
0
        fn from(s: &'a BStr) -> &'a [u8] {
793
0
            BStr::as_bytes(s)
794
0
        }
795
    }
796
797
    impl<'a> From<&'a str> for &'a BStr {
798
        #[inline]
799
0
        fn from(s: &'a str) -> &'a BStr {
800
0
            BStr::from_bytes(s.as_bytes())
801
0
        }
802
    }
803
804
    #[cfg(feature = "alloc")]
805
    impl<'a> From<&'a BStr> for Cow<'a, BStr> {
806
        #[inline]
807
0
        fn from(s: &'a BStr) -> Cow<'a, BStr> {
808
0
            Cow::Borrowed(s)
809
0
        }
810
    }
811
812
    #[cfg(feature = "alloc")]
813
    impl From<Box<[u8]>> for Box<BStr> {
814
        #[inline]
815
0
        fn from(s: Box<[u8]>) -> Box<BStr> {
816
0
            BStr::from_boxed_bytes(s)
817
0
        }
818
    }
819
820
    #[cfg(feature = "alloc")]
821
    impl From<Box<BStr>> for Box<[u8]> {
822
        #[inline]
823
0
        fn from(s: Box<BStr>) -> Box<[u8]> {
824
0
            BStr::into_boxed_bytes(s)
825
0
        }
826
    }
827
828
    impl<'a> TryFrom<&'a BStr> for &'a str {
829
        type Error = crate::Utf8Error;
830
831
        #[inline]
832
0
        fn try_from(s: &'a BStr) -> Result<&'a str, crate::Utf8Error> {
833
0
            s.as_bytes().to_str()
834
0
        }
835
    }
836
837
    #[cfg(feature = "alloc")]
838
    impl<'a> TryFrom<&'a BStr> for String {
839
        type Error = crate::Utf8Error;
840
841
        #[inline]
842
0
        fn try_from(s: &'a BStr) -> Result<String, crate::Utf8Error> {
843
0
            Ok(s.as_bytes().to_str()?.into())
844
0
        }
845
    }
846
847
    #[cfg(feature = "alloc")]
848
    impl Clone for Box<BStr> {
849
        #[inline]
850
0
        fn clone(&self) -> Self {
851
0
            BStr::from_boxed_bytes(self.as_bytes().into())
852
0
        }
853
    }
854
855
    impl Eq for BStr {}
856
857
    impl PartialEq<BStr> for BStr {
858
        #[inline]
859
0
        fn eq(&self, other: &BStr) -> bool {
860
0
            self.as_bytes() == other.as_bytes()
861
0
        }
862
    }
863
864
    impl_partial_eq!(BStr, [u8]);
865
    impl_partial_eq!(BStr, &'a [u8]);
866
    impl_partial_eq!(BStr, str);
867
    impl_partial_eq!(BStr, &'a str);
868
    impl_partial_eq_n!(BStr, [u8; N]);
869
    impl_partial_eq_n!(BStr, &'a [u8; N]);
870
871
    #[cfg(feature = "alloc")]
872
    impl_partial_eq!(BStr, Vec<u8>);
873
    #[cfg(feature = "alloc")]
874
    impl_partial_eq!(&'a BStr, Vec<u8>);
875
    #[cfg(feature = "alloc")]
876
    impl_partial_eq!(BStr, String);
877
    #[cfg(feature = "alloc")]
878
    impl_partial_eq!(&'a BStr, String);
879
    #[cfg(feature = "alloc")]
880
    impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>);
881
    #[cfg(feature = "alloc")]
882
    impl_partial_eq_cow!(&'a BStr, Cow<'a, str>);
883
    #[cfg(feature = "alloc")]
884
    impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>);
885
886
    impl hash::Hash for BStr {
887
        #[inline]
888
0
        fn hash<H: hash::Hasher>(&self, state: &mut H) {
889
0
            self.as_bytes().hash(state);
890
0
        }
891
    }
892
893
    impl PartialOrd for BStr {
894
        #[inline]
895
0
        fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
896
0
            PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
897
0
        }
898
    }
899
900
    impl Ord for BStr {
901
        #[inline]
902
0
        fn cmp(&self, other: &BStr) -> Ordering {
903
0
            self.partial_cmp(other).unwrap()
904
0
        }
905
    }
906
907
    impl_partial_ord!(BStr, [u8]);
908
    impl_partial_ord!(BStr, &'a [u8]);
909
    impl_partial_ord!(BStr, str);
910
    impl_partial_ord!(BStr, &'a str);
911
    impl_partial_ord_n!(BStr, [u8; N]);
912
    impl_partial_ord_n!(BStr, &'a [u8; N]);
913
914
    #[cfg(feature = "alloc")]
915
    impl_partial_ord!(BStr, Vec<u8>);
916
    #[cfg(feature = "alloc")]
917
    impl_partial_ord!(&'a BStr, Vec<u8>);
918
    #[cfg(feature = "alloc")]
919
    impl_partial_ord!(BStr, String);
920
    #[cfg(feature = "alloc")]
921
    impl_partial_ord!(&'a BStr, String);
922
}
923
924
#[cfg(feature = "serde")]
925
mod bstr_serde {
926
    use core::fmt;
927
928
    use serde::{
929
        de::Error, de::Visitor, Deserialize, Deserializer, Serialize,
930
        Serializer,
931
    };
932
933
    use crate::bstr::BStr;
934
935
    impl Serialize for BStr {
936
        #[inline]
937
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
938
        where
939
            S: Serializer,
940
        {
941
            serializer.serialize_bytes(self.as_bytes())
942
        }
943
    }
944
945
    impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr {
946
        #[inline]
947
        fn deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error>
948
        where
949
            D: Deserializer<'de>,
950
        {
951
            struct BStrVisitor;
952
953
            impl<'de> Visitor<'de> for BStrVisitor {
954
                type Value = &'de BStr;
955
956
                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
957
                    f.write_str("a borrowed byte string")
958
                }
959
960
                #[inline]
961
                fn visit_borrowed_bytes<E: Error>(
962
                    self,
963
                    value: &'de [u8],
964
                ) -> Result<&'de BStr, E> {
965
                    Ok(BStr::new(value))
966
                }
967
968
                #[inline]
969
                fn visit_borrowed_str<E: Error>(
970
                    self,
971
                    value: &'de str,
972
                ) -> Result<&'de BStr, E> {
973
                    Ok(BStr::new(value))
974
                }
975
            }
976
977
            deserializer.deserialize_bytes(BStrVisitor)
978
        }
979
    }
980
}
981
982
#[cfg(all(feature = "serde", feature = "alloc"))]
983
mod bstring_serde {
984
    use core::{cmp, fmt};
985
986
    use alloc::{boxed::Box, string::String, vec::Vec};
987
988
    use serde::{
989
        de::Error, de::SeqAccess, de::Visitor, Deserialize, Deserializer,
990
        Serialize, Serializer,
991
    };
992
993
    use crate::{bstr::BStr, bstring::BString};
994
995
    impl Serialize for BString {
996
        #[inline]
997
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
998
        where
999
            S: Serializer,
1000
        {
1001
            serializer.serialize_bytes(self.as_bytes())
1002
        }
1003
    }
1004
1005
    impl<'de> Deserialize<'de> for BString {
1006
        #[inline]
1007
        fn deserialize<D>(deserializer: D) -> Result<BString, D::Error>
1008
        where
1009
            D: Deserializer<'de>,
1010
        {
1011
            struct BStringVisitor;
1012
1013
            impl<'de> Visitor<'de> for BStringVisitor {
1014
                type Value = BString;
1015
1016
                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1017
                    f.write_str("a byte string")
1018
                }
1019
1020
                #[inline]
1021
                fn visit_seq<V: SeqAccess<'de>>(
1022
                    self,
1023
                    mut visitor: V,
1024
                ) -> Result<BString, V::Error> {
1025
                    let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
1026
                    let mut bytes = Vec::with_capacity(len);
1027
                    while let Some(v) = visitor.next_element()? {
1028
                        bytes.push(v);
1029
                    }
1030
                    Ok(BString::from(bytes))
1031
                }
1032
1033
                #[inline]
1034
                fn visit_bytes<E: Error>(
1035
                    self,
1036
                    value: &[u8],
1037
                ) -> Result<BString, E> {
1038
                    Ok(BString::from(value))
1039
                }
1040
1041
                #[inline]
1042
                fn visit_byte_buf<E: Error>(
1043
                    self,
1044
                    value: Vec<u8>,
1045
                ) -> Result<BString, E> {
1046
                    Ok(BString::from(value))
1047
                }
1048
1049
                #[inline]
1050
                fn visit_str<E: Error>(
1051
                    self,
1052
                    value: &str,
1053
                ) -> Result<BString, E> {
1054
                    Ok(BString::from(value))
1055
                }
1056
1057
                #[inline]
1058
                fn visit_string<E: Error>(
1059
                    self,
1060
                    value: String,
1061
                ) -> Result<BString, E> {
1062
                    Ok(BString::from(value))
1063
                }
1064
            }
1065
1066
            deserializer.deserialize_byte_buf(BStringVisitor)
1067
        }
1068
    }
1069
1070
    impl<'de> Deserialize<'de> for Box<BStr> {
1071
        #[inline]
1072
        fn deserialize<D>(deserializer: D) -> Result<Box<BStr>, D::Error>
1073
        where
1074
            D: Deserializer<'de>,
1075
        {
1076
            struct BoxedBStrVisitor;
1077
1078
            impl<'de> Visitor<'de> for BoxedBStrVisitor {
1079
                type Value = Box<BStr>;
1080
1081
                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1082
                    f.write_str("a boxed byte string")
1083
                }
1084
1085
                #[inline]
1086
                fn visit_seq<V: SeqAccess<'de>>(
1087
                    self,
1088
                    mut visitor: V,
1089
                ) -> Result<Box<BStr>, V::Error> {
1090
                    let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
1091
                    let mut bytes = Vec::with_capacity(len);
1092
                    while let Some(v) = visitor.next_element()? {
1093
                        bytes.push(v);
1094
                    }
1095
                    Ok(BStr::from_boxed_bytes(bytes.into_boxed_slice()))
1096
                }
1097
1098
                #[inline]
1099
                fn visit_bytes<E: Error>(
1100
                    self,
1101
                    value: &[u8],
1102
                ) -> Result<Box<BStr>, E> {
1103
                    Ok(BStr::from_boxed_bytes(
1104
                        value.to_vec().into_boxed_slice(),
1105
                    ))
1106
                }
1107
1108
                #[inline]
1109
                fn visit_byte_buf<E: Error>(
1110
                    self,
1111
                    value: Vec<u8>,
1112
                ) -> Result<Box<BStr>, E> {
1113
                    Ok(BStr::from_boxed_bytes(value.into_boxed_slice()))
1114
                }
1115
1116
                #[inline]
1117
                fn visit_str<E: Error>(
1118
                    self,
1119
                    value: &str,
1120
                ) -> Result<Box<BStr>, E> {
1121
                    Ok(BStr::from_boxed_bytes(
1122
                        value.as_bytes().to_vec().into_boxed_slice(),
1123
                    ))
1124
                }
1125
1126
                #[inline]
1127
                fn visit_string<E: Error>(
1128
                    self,
1129
                    value: String,
1130
                ) -> Result<Box<BStr>, E> {
1131
                    Ok(BStr::from_boxed_bytes(
1132
                        value.into_bytes().into_boxed_slice(),
1133
                    ))
1134
                }
1135
            }
1136
1137
            deserializer.deserialize_byte_buf(BoxedBStrVisitor)
1138
        }
1139
    }
1140
}
1141
1142
#[cfg(all(test, feature = "std"))]
1143
mod display {
1144
    use alloc::format;
1145
1146
    #[cfg(not(miri))]
1147
    use crate::bstring::BString;
1148
    use crate::ByteSlice;
1149
1150
    #[test]
1151
    fn clean() {
1152
        assert_eq!(&format!("{}", &b"abc".as_bstr()), "abc");
1153
        assert_eq!(&format!("{}", &b"\xf0\x28\x8c\xbc".as_bstr()), "�(��");
1154
    }
1155
1156
    #[test]
1157
    fn from_str() {
1158
        let s: BString = "abc".parse().unwrap();
1159
        assert_eq!(s, BString::new(b"abc".to_vec()));
1160
    }
1161
1162
    #[test]
1163
    fn width_bigger_than_bstr() {
1164
        assert_eq!(&format!("{:<7}!", &b"abc".as_bstr()), "abc    !");
1165
        assert_eq!(&format!("{:>7}!", &b"abc".as_bstr()), "    abc!");
1166
        assert_eq!(&format!("{:^7}!", &b"abc".as_bstr()), "  abc  !");
1167
        assert_eq!(&format!("{:^6}!", &b"abc".as_bstr()), " abc  !");
1168
        assert_eq!(&format!("{:-<7}!", &b"abc".as_bstr()), "abc----!");
1169
        assert_eq!(&format!("{:->7}!", &b"abc".as_bstr()), "----abc!");
1170
        assert_eq!(&format!("{:-^7}!", &b"abc".as_bstr()), "--abc--!");
1171
        assert_eq!(&format!("{:-^6}!", &b"abc".as_bstr()), "-abc--!");
1172
1173
        assert_eq!(
1174
            &format!("{:<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1175
            "�(��   !"
1176
        );
1177
        assert_eq!(
1178
            &format!("{:>7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1179
            "   �(��!"
1180
        );
1181
        assert_eq!(
1182
            &format!("{:^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1183
            " �(��  !"
1184
        );
1185
        assert_eq!(
1186
            &format!("{:^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1187
            " �(�� !"
1188
        );
1189
1190
        assert_eq!(
1191
            &format!("{:-<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1192
            "�(��---!"
1193
        );
1194
        assert_eq!(
1195
            &format!("{:->7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1196
            "---�(��!"
1197
        );
1198
        assert_eq!(
1199
            &format!("{:-^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1200
            "-�(��--!"
1201
        );
1202
        assert_eq!(
1203
            &format!("{:-^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1204
            "-�(��-!"
1205
        );
1206
    }
1207
1208
    #[test]
1209
    fn width_lesser_than_bstr() {
1210
        assert_eq!(&format!("{:<2}!", &b"abc".as_bstr()), "abc!");
1211
        assert_eq!(&format!("{:>2}!", &b"abc".as_bstr()), "abc!");
1212
        assert_eq!(&format!("{:^2}!", &b"abc".as_bstr()), "abc!");
1213
        assert_eq!(&format!("{:-<2}!", &b"abc".as_bstr()), "abc!");
1214
        assert_eq!(&format!("{:->2}!", &b"abc".as_bstr()), "abc!");
1215
        assert_eq!(&format!("{:-^2}!", &b"abc".as_bstr()), "abc!");
1216
1217
        assert_eq!(
1218
            &format!("{:<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1219
            "�(��!"
1220
        );
1221
        assert_eq!(
1222
            &format!("{:>3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1223
            "�(��!"
1224
        );
1225
        assert_eq!(
1226
            &format!("{:^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1227
            "�(��!"
1228
        );
1229
        assert_eq!(
1230
            &format!("{:^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1231
            "�(��!"
1232
        );
1233
1234
        assert_eq!(
1235
            &format!("{:-<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1236
            "�(��!"
1237
        );
1238
        assert_eq!(
1239
            &format!("{:->3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1240
            "�(��!"
1241
        );
1242
        assert_eq!(
1243
            &format!("{:-^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1244
            "�(��!"
1245
        );
1246
        assert_eq!(
1247
            &format!("{:-^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
1248
            "�(��!"
1249
        );
1250
    }
1251
1252
    #[cfg(not(miri))]
1253
    quickcheck::quickcheck! {
1254
        fn total_length(bstr: BString) -> bool {
1255
            let size = bstr.chars().count();
1256
            format!("{:<1$}", bstr.as_bstr(), size).chars().count() >= size
1257
        }
1258
    }
1259
}
1260
1261
#[cfg(all(test, feature = "alloc"))]
1262
mod bstring_arbitrary {
1263
    use alloc::{boxed::Box, vec::Vec};
1264
1265
    use crate::bstring::BString;
1266
1267
    use quickcheck::{Arbitrary, Gen};
1268
1269
    impl Arbitrary for BString {
1270
        fn arbitrary(g: &mut Gen) -> BString {
1271
            BString::from(Vec::<u8>::arbitrary(g))
1272
        }
1273
1274
        fn shrink(&self) -> Box<dyn Iterator<Item = BString>> {
1275
            Box::new(self.as_vec().shrink().map(BString::from))
1276
        }
1277
    }
1278
}
1279
1280
#[test]
1281
#[cfg(feature = "std")]
1282
fn test_debug() {
1283
    use alloc::format;
1284
1285
    use crate::{ByteSlice, B};
1286
1287
    assert_eq!(
1288
        r#""\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp""#,
1289
        format!("{:?}", b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp".as_bstr()),
1290
    );
1291
1292
    // Tests that if the underlying bytes contain the UTF-8 encoding of the
1293
    // replacement codepoint, then we emit the codepoint just like other
1294
    // non-printable Unicode characters.
1295
    assert_eq!(
1296
        b"\"\\xff\xef\xbf\xbd\\xff\"".as_bstr(),
1297
        // Before fixing #72, the output here would be:
1298
        //   \\xFF\\xEF\\xBF\\xBD\\xFF
1299
        B(&format!("{:?}", b"\xff\xef\xbf\xbd\xff".as_bstr())).as_bstr(),
1300
    );
1301
1302
    // Tests that all ASCII control characters are in lower case.
1303
    assert_eq!(
1304
        b"\"\\xed\\xa0\\x80Aa\\x7f\\x0b\"".as_bstr(),
1305
        // Before fixing #188, the output here would be:
1306
        //   \\xED\\xA0\\x80Aa\\x7f\\x0b
1307
        B(&format!("{:?}", b"\xed\xa0\x80Aa\x7f\x0b".as_bstr())).as_bstr(),
1308
    );
1309
1310
    assert_eq!(
1311
        r#""\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff""#,
1312
        format!("{:?}", b"\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff".as_bstr()),
1313
    );
1314
}
1315
1316
// See: https://github.com/BurntSushi/bstr/issues/82
1317
#[test]
1318
#[cfg(feature = "std")]
1319
fn test_cows_regression() {
1320
    use std::borrow::Cow;
1321
1322
    use crate::ByteSlice;
1323
1324
    let c1 = Cow::from(b"hello bstr".as_bstr());
1325
    let c2 = b"goodbye bstr".as_bstr();
1326
    assert_ne!(c1, c2);
1327
1328
    let c3 = Cow::from("hello str");
1329
    let c4 = "goodbye str";
1330
    assert_ne!(c3, c4);
1331
}
1332
1333
#[test]
1334
#[cfg(feature = "alloc")]
1335
fn test_eq_ord() {
1336
    use core::cmp::Ordering;
1337
1338
    use crate::{BStr, BString};
1339
1340
    let b = BStr::new("hello");
1341
    assert_eq!(b, b"hello");
1342
    assert_ne!(b, b"world");
1343
    assert_eq!(b.partial_cmp(b"hello"), Some(Ordering::Equal));
1344
    assert_eq!(b.partial_cmp(b"world"), Some(Ordering::Less));
1345
1346
    let b = BString::from("hello");
1347
    assert_eq!(b, b"hello");
1348
    assert_ne!(b, b"world");
1349
    assert_eq!(b.partial_cmp(b"hello"), Some(Ordering::Equal));
1350
    assert_eq!(b.partial_cmp(b"world"), Some(Ordering::Less));
1351
}