Coverage Report

Created: 2026-06-30 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bstr-1.12.3/src/ext_slice.rs
Line
Count
Source
1
use core::{iter, slice, str};
2
3
#[cfg(all(feature = "alloc", feature = "unicode"))]
4
use alloc::vec;
5
#[cfg(feature = "alloc")]
6
use alloc::{borrow::Cow, string::String, vec::Vec};
7
8
#[cfg(feature = "std")]
9
use std::{ffi::OsStr, path::Path};
10
11
use memchr::{memchr, memmem, memrchr};
12
13
use crate::escape_bytes::EscapeBytes;
14
#[cfg(feature = "alloc")]
15
use crate::ext_vec::ByteVec;
16
#[cfg(feature = "unicode")]
17
use crate::unicode::{
18
    whitespace_len_fwd, whitespace_len_rev, GraphemeIndices, Graphemes,
19
    SentenceIndices, Sentences, WordIndices, Words, WordsWithBreakIndices,
20
    WordsWithBreaks,
21
};
22
use crate::{
23
    ascii,
24
    bstr::BStr,
25
    byteset,
26
    utf8::{self, CharIndices, Chars, Utf8Chunks, Utf8Error},
27
};
28
29
/// A short-hand constructor for building a `&[u8]`.
30
///
31
/// This idiosyncratic constructor is useful for concisely building byte string
32
/// slices. Its primary utility is in conveniently writing byte string literals
33
/// in a uniform way. For example, consider this code that does not compile:
34
///
35
/// ```ignore
36
/// let strs = vec![b"a", b"xy"];
37
/// ```
38
///
39
/// The above code doesn't compile because the type of the byte string literal
40
/// `b"a"` is `&'static [u8; 1]`, and the type of `b"xy"` is
41
/// `&'static [u8; 2]`. Since their types aren't the same, they can't be stored
42
/// in the same `Vec`. (This is dissimilar from normal Unicode string slices,
43
/// where both `"a"` and `"xy"` have the same type of `&'static str`.)
44
///
45
/// One way of getting the above code to compile is to convert byte strings to
46
/// slices. You might try this:
47
///
48
/// ```ignore
49
/// let strs = vec![&b"a", &b"xy"];
50
/// ```
51
///
52
/// But this just creates values with type `& &'static [u8; 1]` and
53
/// `& &'static [u8; 2]`. Instead, you need to force the issue like so:
54
///
55
/// ```
56
/// let strs = vec![&b"a"[..], &b"xy"[..]];
57
/// // or
58
/// let strs = vec![b"a".as_ref(), b"xy".as_ref()];
59
/// ```
60
///
61
/// But neither of these are particularly convenient to type, especially when
62
/// it's something as common as a string literal. Thus, this constructor
63
/// permits writing the following instead:
64
///
65
/// ```
66
/// use bstr::B;
67
///
68
/// let strs = vec![B("a"), B(b"xy")];
69
/// ```
70
///
71
/// Notice that this also lets you mix and match both string literals and byte
72
/// string literals. This can be quite convenient!
73
#[allow(non_snake_case)]
74
#[inline]
75
0
pub fn B<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &[u8] {
76
0
    bytes.as_ref()
77
0
}
Unexecuted instantiation: bstr::ext_slice::B::<_>
Unexecuted instantiation: bstr::ext_slice::B::<_>
Unexecuted instantiation: bstr::ext_slice::B::<_>
78
79
impl ByteSlice for [u8] {
80
    #[inline]
81
1.03G
    fn as_bytes(&self) -> &[u8] {
82
1.03G
        self
83
1.03G
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
81
10.1M
    fn as_bytes(&self) -> &[u8] {
82
10.1M
        self
83
10.1M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
81
90.7M
    fn as_bytes(&self) -> &[u8] {
82
90.7M
        self
83
90.7M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
81
724M
    fn as_bytes(&self) -> &[u8] {
82
724M
        self
83
724M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
81
211M
    fn as_bytes(&self) -> &[u8] {
82
211M
        self
83
211M
    }
84
85
    #[inline]
86
0
    fn as_bytes_mut(&mut self) -> &mut [u8] {
87
0
        self
88
0
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bytes_mut
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bytes_mut
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bytes_mut
89
}
90
91
impl<const N: usize> ByteSlice for [u8; N] {
92
    #[inline]
93
104k
    fn as_bytes(&self) -> &[u8] {
94
104k
        self
95
104k
    }
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 1] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
26.0k
    fn as_bytes(&self) -> &[u8] {
94
26.0k
        self
95
26.0k
    }
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 19] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 10] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
21.9k
    fn as_bytes(&self) -> &[u8] {
94
21.9k
        self
95
21.9k
    }
<[u8; 11] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
6.67k
    fn as_bytes(&self) -> &[u8] {
94
6.67k
        self
95
6.67k
    }
<[u8; 12] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
3.28k
    fn as_bytes(&self) -> &[u8] {
94
3.28k
        self
95
3.28k
    }
<[u8; 13] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
3.31k
    fn as_bytes(&self) -> &[u8] {
94
3.31k
        self
95
3.31k
    }
<[u8; 14] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
22.1k
    fn as_bytes(&self) -> &[u8] {
94
22.1k
        self
95
22.1k
    }
<[u8; 15] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
3.21k
    fn as_bytes(&self) -> &[u8] {
94
3.21k
        self
95
3.21k
    }
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
804
    fn as_bytes(&self) -> &[u8] {
94
804
        self
95
804
    }
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
193
    fn as_bytes(&self) -> &[u8] {
94
193
        self
95
193
    }
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
1.67k
    fn as_bytes(&self) -> &[u8] {
94
1.67k
        self
95
1.67k
    }
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
1.20k
    fn as_bytes(&self) -> &[u8] {
94
1.20k
        self
95
1.20k
    }
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
<[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Line
Count
Source
93
14.5k
    fn as_bytes(&self) -> &[u8] {
94
14.5k
        self
95
14.5k
    }
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bytes
96
97
    #[inline]
98
0
    fn as_bytes_mut(&mut self) -> &mut [u8] {
99
0
        self
100
0
    }
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes_mut
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes_mut
Unexecuted instantiation: <[u8; _] as bstr::ext_slice::ByteSlice>::as_bytes_mut
101
}
102
103
/// Ensure that callers cannot implement `ByteSlice` by making an
104
/// umplementable trait its super trait.
105
mod private {
106
    pub trait Sealed {}
107
}
108
impl private::Sealed for [u8] {}
109
impl<const N: usize> private::Sealed for [u8; N] {}
110
111
/// A trait that extends `&[u8]` with string oriented methods.
112
///
113
/// This trait is sealed and cannot be implemented outside of `bstr`.
114
pub trait ByteSlice: private::Sealed {
115
    /// A method for accessing the raw bytes of this type. This is always a
116
    /// no-op and callers shouldn't care about it. This only exists for making
117
    /// the extension trait work.
118
    #[doc(hidden)]
119
    fn as_bytes(&self) -> &[u8];
120
121
    /// A method for accessing the raw bytes of this type, mutably. This is
122
    /// always a no-op and callers shouldn't care about it. This only exists
123
    /// for making the extension trait work.
124
    #[doc(hidden)]
125
    fn as_bytes_mut(&mut self) -> &mut [u8];
126
127
    /// Return this byte slice as a `&BStr`.
128
    ///
129
    /// Use `&BStr` is useful because of its `fmt::Debug` representation
130
    /// and various other trait implementations (such as `PartialEq` and
131
    /// `PartialOrd`). In particular, the `Debug` implementation for `BStr`
132
    /// shows its bytes as a normal string. For invalid UTF-8, hex escape
133
    /// sequences are used.
134
    ///
135
    /// # Examples
136
    ///
137
    /// Basic usage:
138
    ///
139
    /// ```
140
    /// use bstr::ByteSlice;
141
    ///
142
    /// println!("{:?}", b"foo\xFFbar".as_bstr());
143
    /// ```
144
    #[inline]
145
276M
    fn as_bstr(&self) -> &BStr {
146
276M
        BStr::new(self.as_bytes())
147
276M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
53.8k
    fn as_bstr(&self) -> &BStr {
146
53.8k
        BStr::new(self.as_bytes())
147
53.8k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.61M
    fn as_bstr(&self) -> &BStr {
146
3.61M
        BStr::new(self.as_bytes())
147
3.61M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
157k
    fn as_bstr(&self) -> &BStr {
146
157k
        BStr::new(self.as_bytes())
147
157k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
6.48k
    fn as_bstr(&self) -> &BStr {
146
6.48k
        BStr::new(self.as_bytes())
147
6.48k
    }
<[u8; 1] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
26.0k
    fn as_bstr(&self) -> &BStr {
146
26.0k
        BStr::new(self.as_bytes())
147
26.0k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
228M
    fn as_bstr(&self) -> &BStr {
146
228M
        BStr::new(self.as_bytes())
147
228M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 19] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8; 10] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
21.9k
    fn as_bstr(&self) -> &BStr {
146
21.9k
        BStr::new(self.as_bytes())
147
21.9k
    }
<[u8; 11] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
6.67k
    fn as_bstr(&self) -> &BStr {
146
6.67k
        BStr::new(self.as_bytes())
147
6.67k
    }
<[u8; 12] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.28k
    fn as_bstr(&self) -> &BStr {
146
3.28k
        BStr::new(self.as_bytes())
147
3.28k
    }
<[u8; 13] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.31k
    fn as_bstr(&self) -> &BStr {
146
3.31k
        BStr::new(self.as_bytes())
147
3.31k
    }
<[u8; 14] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
22.1k
    fn as_bstr(&self) -> &BStr {
146
22.1k
        BStr::new(self.as_bytes())
147
22.1k
    }
<[u8; 15] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.21k
    fn as_bstr(&self) -> &BStr {
146
3.21k
        BStr::new(self.as_bytes())
147
3.21k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
6.07M
    fn as_bstr(&self) -> &BStr {
146
6.07M
        BStr::new(self.as_bytes())
147
6.07M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
211k
    fn as_bstr(&self) -> &BStr {
146
211k
        BStr::new(self.as_bytes())
147
211k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
804
    fn as_bstr(&self) -> &BStr {
146
804
        BStr::new(self.as_bytes())
147
804
    }
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
193
    fn as_bstr(&self) -> &BStr {
146
193
        BStr::new(self.as_bytes())
147
193
    }
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
6.54M
    fn as_bstr(&self) -> &BStr {
146
6.54M
        BStr::new(self.as_bytes())
147
6.54M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
346
    fn as_bstr(&self) -> &BStr {
146
346
        BStr::new(self.as_bytes())
147
346
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
577k
    fn as_bstr(&self) -> &BStr {
146
577k
        BStr::new(self.as_bytes())
147
577k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
1.76k
    fn as_bstr(&self) -> &BStr {
146
1.76k
        BStr::new(self.as_bytes())
147
1.76k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
1.00k
    fn as_bstr(&self) -> &BStr {
146
1.00k
        BStr::new(self.as_bytes())
147
1.00k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
97.6k
    fn as_bstr(&self) -> &BStr {
146
97.6k
        BStr::new(self.as_bytes())
147
97.6k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
39.6k
    fn as_bstr(&self) -> &BStr {
146
39.6k
        BStr::new(self.as_bytes())
147
39.6k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.37M
    fn as_bstr(&self) -> &BStr {
146
3.37M
        BStr::new(self.as_bytes())
147
3.37M
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
328k
    fn as_bstr(&self) -> &BStr {
146
328k
        BStr::new(self.as_bytes())
147
328k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
17.8k
    fn as_bstr(&self) -> &BStr {
146
17.8k
        BStr::new(self.as_bytes())
147
17.8k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
2.27k
    fn as_bstr(&self) -> &BStr {
146
2.27k
        BStr::new(self.as_bytes())
147
2.27k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.00k
    fn as_bstr(&self) -> &BStr {
146
3.00k
        BStr::new(self.as_bytes())
147
3.00k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
53.7k
    fn as_bstr(&self) -> &BStr {
146
53.7k
        BStr::new(self.as_bytes())
147
53.7k
    }
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
1.67k
    fn as_bstr(&self) -> &BStr {
146
1.67k
        BStr::new(self.as_bytes())
147
1.67k
    }
<[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
1.20k
    fn as_bstr(&self) -> &BStr {
146
1.20k
        BStr::new(self.as_bytes())
147
1.20k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
14.4M
    fn as_bstr(&self) -> &BStr {
146
14.4M
        BStr::new(self.as_bytes())
147
14.4M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
14.5k
    fn as_bstr(&self) -> &BStr {
146
14.5k
        BStr::new(self.as_bytes())
147
14.5k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
48.1k
    fn as_bstr(&self) -> &BStr {
146
48.1k
        BStr::new(self.as_bytes())
147
48.1k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
300k
    fn as_bstr(&self) -> &BStr {
146
300k
        BStr::new(self.as_bytes())
147
300k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.32M
    fn as_bstr(&self) -> &BStr {
146
3.32M
        BStr::new(self.as_bytes())
147
3.32M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
52.5k
    fn as_bstr(&self) -> &BStr {
146
52.5k
        BStr::new(self.as_bytes())
147
52.5k
    }
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
38.0k
    fn as_bstr(&self) -> &BStr {
146
38.0k
        BStr::new(self.as_bytes())
147
38.0k
    }
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 4] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
3.60M
    fn as_bstr(&self) -> &BStr {
146
3.60M
        BStr::new(self.as_bytes())
147
3.60M
    }
Unexecuted instantiation: <[u8; 0] as bstr::ext_slice::ByteSlice>::as_bstr
<[u8] as bstr::ext_slice::ByteSlice>::as_bstr
Line
Count
Source
145
4.83M
    fn as_bstr(&self) -> &BStr {
146
4.83M
        BStr::new(self.as_bytes())
147
4.83M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::as_bstr
148
149
    /// Return this byte slice as a `&mut BStr`.
150
    ///
151
    /// Use `&mut BStr` is useful because of its `fmt::Debug` representation
152
    /// and various other trait implementations (such as `PartialEq` and
153
    /// `PartialOrd`). In particular, the `Debug` implementation for `BStr`
154
    /// shows its bytes as a normal string. For invalid UTF-8, hex escape
155
    /// sequences are used.
156
    ///
157
    /// # Examples
158
    ///
159
    /// Basic usage:
160
    ///
161
    /// ```
162
    /// use bstr::ByteSlice;
163
    ///
164
    /// let mut bytes = *b"foo\xFFbar";
165
    /// println!("{:?}", &mut bytes.as_bstr_mut());
166
    /// ```
167
    #[inline]
168
0
    fn as_bstr_mut(&mut self) -> &mut BStr {
169
0
        BStr::new_mut(self.as_bytes_mut())
170
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr_mut
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr_mut
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::as_bstr_mut
171
172
    /// Create an immutable byte string from an OS string slice.
173
    ///
174
    /// When the underlying bytes of OS strings are accessible, then this
175
    /// always succeeds and is zero cost. Otherwise, this returns `None` if the
176
    /// given OS string is not valid UTF-8. (For example, when the underlying
177
    /// bytes are inaccessible on Windows, file paths are allowed to be a
178
    /// sequence of arbitrary 16-bit integers. Not all such sequences can be
179
    /// transcoded to valid UTF-8.)
180
    ///
181
    /// # Examples
182
    ///
183
    /// Basic usage:
184
    ///
185
    /// ```
186
    /// use std::ffi::OsStr;
187
    ///
188
    /// use bstr::{B, ByteSlice};
189
    ///
190
    /// let os_str = OsStr::new("foo");
191
    /// let bs = <[u8]>::from_os_str(os_str).expect("should be valid UTF-8");
192
    /// assert_eq!(bs, B("foo"));
193
    /// ```
194
    #[cfg(feature = "std")]
195
    #[inline]
196
0
    fn from_os_str(os_str: &OsStr) -> Option<&[u8]> {
197
        #[cfg(unix)]
198
        #[inline]
199
0
        fn imp(os_str: &OsStr) -> Option<&[u8]> {
200
            use std::os::unix::ffi::OsStrExt;
201
202
0
            Some(os_str.as_bytes())
203
0
        }
Unexecuted instantiation: bstr::ext_slice::ByteSlice::from_os_str::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::from_os_str::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::from_os_str::imp
204
205
        #[cfg(not(unix))]
206
        #[inline]
207
        fn imp(os_str: &OsStr) -> Option<&[u8]> {
208
            os_str.to_str().map(|s| s.as_bytes())
209
        }
210
211
0
        imp(os_str)
212
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_os_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_os_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_os_str
213
214
    /// Create an immutable byte string from a file path.
215
    ///
216
    /// When the underlying bytes of paths are accessible, then this always
217
    /// succeeds and is zero cost. Otherwise, this returns `None` if the given
218
    /// path is not valid UTF-8. (For example, when the underlying bytes are
219
    /// inaccessible on Windows, file paths are allowed to be a sequence of
220
    /// arbitrary 16-bit integers. Not all such sequences can be transcoded to
221
    /// valid UTF-8.)
222
    ///
223
    /// # Examples
224
    ///
225
    /// Basic usage:
226
    ///
227
    /// ```
228
    /// use std::path::Path;
229
    ///
230
    /// use bstr::{B, ByteSlice};
231
    ///
232
    /// let path = Path::new("foo");
233
    /// let bs = <[u8]>::from_path(path).expect("should be valid UTF-8");
234
    /// assert_eq!(bs, B("foo"));
235
    /// ```
236
    #[cfg(feature = "std")]
237
    #[inline]
238
0
    fn from_path(path: &Path) -> Option<&[u8]> {
239
0
        Self::from_os_str(path.as_os_str())
240
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_path
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_path
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::from_path
241
242
    /// Safely convert this byte string into a `&str` if it's valid UTF-8.
243
    ///
244
    /// If this byte string is not valid UTF-8, then an error is returned. The
245
    /// error returned indicates the first invalid byte found and the length
246
    /// of the error.
247
    ///
248
    /// In cases where a lossy conversion to `&str` is acceptable, then use one
249
    /// of the [`to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy) or
250
    /// [`to_str_lossy_into`](trait.ByteSlice.html#method.to_str_lossy_into)
251
    /// methods.
252
    ///
253
    /// # Examples
254
    ///
255
    /// Basic usage:
256
    ///
257
    /// ```
258
    /// # #[cfg(feature = "alloc")] {
259
    /// use bstr::{B, ByteSlice, ByteVec};
260
    ///
261
    /// # fn example() -> Result<(), bstr::Utf8Error> {
262
    /// let s = B("☃βツ").to_str()?;
263
    /// assert_eq!("☃βツ", s);
264
    ///
265
    /// let mut bstring = <Vec<u8>>::from("☃βツ");
266
    /// bstring.push(b'\xFF');
267
    /// let err = bstring.to_str().unwrap_err();
268
    /// assert_eq!(8, err.valid_up_to());
269
    /// # Ok(()) }; example().unwrap()
270
    /// # }
271
    /// ```
272
    #[inline]
273
5.77M
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
5.77M
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
5.51M
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
5.51M
        })
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
633k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
633k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
633k
        })
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
561
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
561
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
561
        })
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
12.8k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
12.8k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
12.8k
        })
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
6.07k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
6.07k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
6.07k
        })
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
55.2k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
55.2k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
55.2k
        })
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
9.85k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
9.85k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
9.85k
        })
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
29.4k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
29.4k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
29.4k
        })
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
19.3k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
19.3k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
19.3k
        })
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
6.96k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
6.96k
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
6.96k
        })
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
<[u8] as bstr::ext_slice::ByteSlice>::to_str::{closure#0}
Line
Count
Source
274
4.73M
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
4.73M
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
4.73M
        })
279
5.77M
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
885k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
885k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
885k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
1.11k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
1.11k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
1.11k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
13.6k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
13.6k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
13.6k
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
6.17k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
6.17k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
6.17k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
55.9k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
55.9k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
55.9k
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
15.4k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
15.4k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
15.4k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
29.4k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
29.4k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
29.4k
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
20.1k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
20.1k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
20.1k
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
7.10k
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
7.10k
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
7.10k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str
<[u8] as bstr::ext_slice::ByteSlice>::to_str
Line
Count
Source
273
4.73M
    fn to_str(&self) -> Result<&str, Utf8Error> {
274
4.73M
        utf8::validate(self.as_bytes()).map(|_| {
275
            // SAFETY: This is safe because of the guarantees provided by
276
            // utf8::validate.
277
            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
278
        })
279
4.73M
    }
280
281
    /// Unsafely convert this byte string into a `&str`, without checking for
282
    /// valid UTF-8.
283
    ///
284
    /// # Safety
285
    ///
286
    /// Callers *must* ensure that this byte string is valid UTF-8 before
287
    /// calling this method. Converting a byte string into a `&str` that is
288
    /// not valid UTF-8 is considered undefined behavior.
289
    ///
290
    /// This routine is useful in performance sensitive contexts where the
291
    /// UTF-8 validity of the byte string is already known and it is
292
    /// undesirable to pay the cost of an additional UTF-8 validation check
293
    /// that [`to_str`](trait.ByteSlice.html#method.to_str) performs.
294
    ///
295
    /// # Examples
296
    ///
297
    /// Basic usage:
298
    ///
299
    /// ```
300
    /// use bstr::{B, ByteSlice};
301
    ///
302
    /// // SAFETY: This is safe because string literals are guaranteed to be
303
    /// // valid UTF-8 by the Rust compiler.
304
    /// let s = unsafe { B("☃βツ").to_str_unchecked() };
305
    /// assert_eq!("☃βツ", s);
306
    /// ```
307
    #[inline]
308
0
    unsafe fn to_str_unchecked(&self) -> &str {
309
0
        str::from_utf8_unchecked(self.as_bytes())
310
0
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_unchecked
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_unchecked
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_unchecked
311
312
    /// Convert this byte string to a valid UTF-8 string by replacing invalid
313
    /// UTF-8 bytes with the Unicode replacement codepoint (`U+FFFD`).
314
    ///
315
    /// If the byte string is already valid UTF-8, then no copying or
316
    /// allocation is performed and a borrrowed string slice is returned. If
317
    /// the byte string is not valid UTF-8, then an owned string buffer is
318
    /// returned with invalid bytes replaced by the replacement codepoint.
319
    ///
320
    /// This method uses the "substitution of maximal subparts" (Unicode
321
    /// Standard, Chapter 3, Section 9) strategy for inserting the replacement
322
    /// codepoint. Specifically, a replacement codepoint is inserted whenever a
323
    /// byte is found that cannot possibly lead to a valid code unit sequence.
324
    /// If there were previous bytes that represented a prefix of a well-formed
325
    /// code unit sequence, then all of those bytes are substituted with a
326
    /// single replacement codepoint. The "substitution of maximal subparts"
327
    /// strategy is the same strategy used by
328
    /// [W3C's Encoding standard](https://www.w3.org/TR/encoding/).
329
    /// For a more precise description of the maximal subpart strategy, see
330
    /// the Unicode Standard, Chapter 3, Section 9. See also
331
    /// [Public Review Issue #121](https://www.unicode.org/review/pr-121.html).
332
    ///
333
    /// N.B. Rust's standard library also appears to use the same strategy,
334
    /// but it does not appear to be an API guarantee.
335
    ///
336
    /// # Examples
337
    ///
338
    /// Basic usage:
339
    ///
340
    /// ```
341
    /// use std::borrow::Cow;
342
    ///
343
    /// use bstr::ByteSlice;
344
    ///
345
    /// let mut bstring = <Vec<u8>>::from("☃βツ");
346
    /// assert_eq!(Cow::Borrowed("☃βツ"), bstring.to_str_lossy());
347
    ///
348
    /// // Add a byte that makes the sequence invalid.
349
    /// bstring.push(b'\xFF');
350
    /// assert_eq!(Cow::Borrowed("☃βツ\u{FFFD}"), bstring.to_str_lossy());
351
    /// ```
352
    ///
353
    /// This demonstrates the "maximal subpart" substitution logic.
354
    ///
355
    /// ```
356
    /// use bstr::{B, ByteSlice};
357
    ///
358
    /// // \x61 is the ASCII codepoint for 'a'.
359
    /// // \xF1\x80\x80 is a valid 3-byte code unit prefix.
360
    /// // \xE1\x80 is a valid 2-byte code unit prefix.
361
    /// // \xC2 is a valid 1-byte code unit prefix.
362
    /// // \x62 is the ASCII codepoint for 'b'.
363
    /// //
364
    /// // In sum, each of the prefixes is replaced by a single replacement
365
    /// // codepoint since none of the prefixes are properly completed. This
366
    /// // is in contrast to other strategies that might insert a replacement
367
    /// // codepoint for every single byte.
368
    /// let bs = B(b"\x61\xF1\x80\x80\xE1\x80\xC2\x62");
369
    /// assert_eq!("a\u{FFFD}\u{FFFD}\u{FFFD}b", bs.to_str_lossy());
370
    /// ```
371
    #[cfg(feature = "alloc")]
372
    #[inline]
373
3.42M
    fn to_str_lossy(&self) -> Cow<'_, str> {
374
3.42M
        match utf8::validate(self.as_bytes()) {
375
            Ok(()) => {
376
                // SAFETY: This is safe because of the guarantees provided by
377
                // utf8::validate.
378
                unsafe {
379
3.36M
                    Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes()))
380
                }
381
            }
382
61.0k
            Err(err) => {
383
61.0k
                let mut lossy = String::with_capacity(self.as_bytes().len());
384
61.0k
                let (valid, after) =
385
61.0k
                    self.as_bytes().split_at(err.valid_up_to());
386
                // SAFETY: This is safe because utf8::validate guarantees
387
                // that all of `valid` is valid UTF-8.
388
61.0k
                lossy.push_str(unsafe { str::from_utf8_unchecked(valid) });
389
61.0k
                lossy.push_str("\u{FFFD}");
390
61.0k
                if let Some(len) = err.error_len() {
391
47.3k
                    after[len..].to_str_lossy_into(&mut lossy);
392
47.3k
                }
393
61.0k
                Cow::Owned(lossy)
394
            }
395
        }
396
3.42M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
<[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
Line
Count
Source
373
3.32M
    fn to_str_lossy(&self) -> Cow<'_, str> {
374
3.32M
        match utf8::validate(self.as_bytes()) {
375
            Ok(()) => {
376
                // SAFETY: This is safe because of the guarantees provided by
377
                // utf8::validate.
378
                unsafe {
379
3.26M
                    Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes()))
380
                }
381
            }
382
61.0k
            Err(err) => {
383
61.0k
                let mut lossy = String::with_capacity(self.as_bytes().len());
384
61.0k
                let (valid, after) =
385
61.0k
                    self.as_bytes().split_at(err.valid_up_to());
386
                // SAFETY: This is safe because utf8::validate guarantees
387
                // that all of `valid` is valid UTF-8.
388
61.0k
                lossy.push_str(unsafe { str::from_utf8_unchecked(valid) });
389
61.0k
                lossy.push_str("\u{FFFD}");
390
61.0k
                if let Some(len) = err.error_len() {
391
47.3k
                    after[len..].to_str_lossy_into(&mut lossy);
392
47.3k
                }
393
61.0k
                Cow::Owned(lossy)
394
            }
395
        }
396
3.32M
    }
<[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy
Line
Count
Source
373
95.5k
    fn to_str_lossy(&self) -> Cow<'_, str> {
374
95.5k
        match utf8::validate(self.as_bytes()) {
375
            Ok(()) => {
376
                // SAFETY: This is safe because of the guarantees provided by
377
                // utf8::validate.
378
                unsafe {
379
95.5k
                    Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes()))
380
                }
381
            }
382
0
            Err(err) => {
383
0
                let mut lossy = String::with_capacity(self.as_bytes().len());
384
0
                let (valid, after) =
385
0
                    self.as_bytes().split_at(err.valid_up_to());
386
                // SAFETY: This is safe because utf8::validate guarantees
387
                // that all of `valid` is valid UTF-8.
388
0
                lossy.push_str(unsafe { str::from_utf8_unchecked(valid) });
389
0
                lossy.push_str("\u{FFFD}");
390
0
                if let Some(len) = err.error_len() {
391
0
                    after[len..].to_str_lossy_into(&mut lossy);
392
0
                }
393
0
                Cow::Owned(lossy)
394
            }
395
        }
396
95.5k
    }
397
398
    /// Copy the contents of this byte string into the given owned string
399
    /// buffer, while replacing invalid UTF-8 code unit sequences with the
400
    /// Unicode replacement codepoint (`U+FFFD`).
401
    ///
402
    /// This method uses the same "substitution of maximal subparts" strategy
403
    /// for inserting the replacement codepoint as the
404
    /// [`to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy) method.
405
    ///
406
    /// This routine is useful for amortizing allocation. However, unlike
407
    /// `to_str_lossy`, this routine will _always_ copy the contents of this
408
    /// byte string into the destination buffer, even if this byte string is
409
    /// valid UTF-8.
410
    ///
411
    /// # Examples
412
    ///
413
    /// Basic usage:
414
    ///
415
    /// ```
416
    /// use std::borrow::Cow;
417
    ///
418
    /// use bstr::ByteSlice;
419
    ///
420
    /// let mut bstring = <Vec<u8>>::from("☃βツ");
421
    /// // Add a byte that makes the sequence invalid.
422
    /// bstring.push(b'\xFF');
423
    ///
424
    /// let mut dest = String::new();
425
    /// bstring.to_str_lossy_into(&mut dest);
426
    /// assert_eq!("☃βツ\u{FFFD}", dest);
427
    /// ```
428
    #[cfg(feature = "alloc")]
429
    #[inline]
430
47.3k
    fn to_str_lossy_into(&self, dest: &mut String) {
431
47.3k
        let mut bytes = self.as_bytes();
432
47.3k
        dest.reserve(bytes.len());
433
        loop {
434
11.2M
            match utf8::validate(bytes) {
435
                Ok(()) => {
436
                    // SAFETY: This is safe because utf8::validate guarantees
437
                    // that all of `bytes` is valid UTF-8.
438
41.2k
                    dest.push_str(unsafe { str::from_utf8_unchecked(bytes) });
439
41.2k
                    break;
440
                }
441
11.1M
                Err(err) => {
442
11.1M
                    let (valid, after) = bytes.split_at(err.valid_up_to());
443
                    // SAFETY: This is safe because utf8::validate guarantees
444
                    // that all of `valid` is valid UTF-8.
445
11.1M
                    dest.push_str(unsafe { str::from_utf8_unchecked(valid) });
446
11.1M
                    dest.push_str("\u{FFFD}");
447
11.1M
                    match err.error_len() {
448
6.13k
                        None => break,
449
11.1M
                        Some(len) => bytes = &after[len..],
450
                    }
451
                }
452
            }
453
        }
454
47.3k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
<[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
Line
Count
Source
430
47.3k
    fn to_str_lossy_into(&self, dest: &mut String) {
431
47.3k
        let mut bytes = self.as_bytes();
432
47.3k
        dest.reserve(bytes.len());
433
        loop {
434
11.2M
            match utf8::validate(bytes) {
435
                Ok(()) => {
436
                    // SAFETY: This is safe because utf8::validate guarantees
437
                    // that all of `bytes` is valid UTF-8.
438
41.2k
                    dest.push_str(unsafe { str::from_utf8_unchecked(bytes) });
439
41.2k
                    break;
440
                }
441
11.1M
                Err(err) => {
442
11.1M
                    let (valid, after) = bytes.split_at(err.valid_up_to());
443
                    // SAFETY: This is safe because utf8::validate guarantees
444
                    // that all of `valid` is valid UTF-8.
445
11.1M
                    dest.push_str(unsafe { str::from_utf8_unchecked(valid) });
446
11.1M
                    dest.push_str("\u{FFFD}");
447
11.1M
                    match err.error_len() {
448
6.13k
                        None => break,
449
11.1M
                        Some(len) => bytes = &after[len..],
450
                    }
451
                }
452
            }
453
        }
454
47.3k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_str_lossy_into
455
456
    /// Create an OS string slice from this byte string.
457
    ///
458
    /// When OS strings can be constructed from arbitrary byte sequences, this
459
    /// always succeeds and is zero cost. Otherwise, this returns a UTF-8
460
    /// decoding error if this byte string is not valid UTF-8. (For example,
461
    /// assuming the representation of `OsStr` is opaque on Windows, file paths
462
    /// are allowed to be a sequence of arbitrary 16-bit integers. There is
463
    /// no obvious mapping from an arbitrary sequence of 8-bit integers to an
464
    /// arbitrary sequence of 16-bit integers. If the representation of `OsStr`
465
    /// is even opened up, then this will convert any sequence of bytes to an
466
    /// `OsStr` without cost.)
467
    ///
468
    /// # Examples
469
    ///
470
    /// Basic usage:
471
    ///
472
    /// ```
473
    /// use bstr::{B, ByteSlice};
474
    ///
475
    /// let os_str = b"foo".to_os_str().expect("should be valid UTF-8");
476
    /// assert_eq!(os_str, "foo");
477
    /// ```
478
    #[cfg(feature = "std")]
479
    #[inline]
480
0
    fn to_os_str(&self) -> Result<&OsStr, Utf8Error> {
481
        #[cfg(unix)]
482
        #[inline]
483
0
        fn imp(bytes: &[u8]) -> Result<&OsStr, Utf8Error> {
484
            use std::os::unix::ffi::OsStrExt;
485
486
0
            Ok(OsStr::from_bytes(bytes))
487
0
        }
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str::imp
488
489
        #[cfg(not(unix))]
490
        #[inline]
491
        fn imp(bytes: &[u8]) -> Result<&OsStr, Utf8Error> {
492
            bytes.to_str().map(OsStr::new)
493
        }
494
495
0
        imp(self.as_bytes())
496
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_os_str
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_os_str
497
498
    /// Lossily create an OS string slice from this byte string.
499
    ///
500
    /// When OS strings can be constructed from arbitrary byte sequences, this
501
    /// is zero cost and always returns a slice. Otherwise, this will perform a
502
    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
503
    /// the Unicode replacement codepoint.
504
    ///
505
    /// Note that this can prevent the correct roundtripping of file paths when
506
    /// the representation of `OsStr` is opaque.
507
    ///
508
    /// # Examples
509
    ///
510
    /// Basic usage:
511
    ///
512
    /// ```
513
    /// use bstr::ByteSlice;
514
    ///
515
    /// let os_str = b"foo\xFFbar".to_os_str_lossy();
516
    /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
517
    /// ```
518
    #[cfg(feature = "std")]
519
    #[inline]
520
0
    fn to_os_str_lossy(&self) -> Cow<'_, OsStr> {
521
        #[cfg(unix)]
522
        #[inline]
523
0
        fn imp(bytes: &[u8]) -> Cow<'_, OsStr> {
524
            use std::os::unix::ffi::OsStrExt;
525
526
0
            Cow::Borrowed(OsStr::from_bytes(bytes))
527
0
        }
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str_lossy::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str_lossy::imp
Unexecuted instantiation: bstr::ext_slice::ByteSlice::to_os_str_lossy::imp
528
529
        #[cfg(not(unix))]
530
        #[inline]
531
        fn imp(bytes: &[u8]) -> Cow<'_, OsStr> {
532
            use std::ffi::OsString;
533
534
            match bytes.to_str_lossy() {
535
                Cow::Borrowed(x) => Cow::Borrowed(OsStr::new(x)),
536
                Cow::Owned(x) => Cow::Owned(OsString::from(x)),
537
            }
538
        }
539
540
0
        imp(self.as_bytes())
541
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_os_str_lossy
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_os_str_lossy
542
543
    /// Create a path slice from this byte string.
544
    ///
545
    /// When paths can be constructed from arbitrary byte sequences, this
546
    /// always succeeds and is zero cost. Otherwise, this returns a UTF-8
547
    /// decoding error if this byte string is not valid UTF-8. (For example,
548
    /// assuming the representation of `Path` is opaque on Windows, file paths
549
    /// are allowed to be a sequence of arbitrary 16-bit integers. There is
550
    /// no obvious mapping from an arbitrary sequence of 8-bit integers to an
551
    /// arbitrary sequence of 16-bit integers. If the representation of `Path`
552
    /// is even opened up, then this will convert any sequence of bytes to an
553
    /// `Path` without cost.)
554
    ///
555
    /// # Examples
556
    ///
557
    /// Basic usage:
558
    ///
559
    /// ```
560
    /// use bstr::ByteSlice;
561
    ///
562
    /// let path = b"foo".to_path().expect("should be valid UTF-8");
563
    /// assert_eq!(path.as_os_str(), "foo");
564
    /// ```
565
    #[cfg(feature = "std")]
566
    #[inline]
567
0
    fn to_path(&self) -> Result<&Path, Utf8Error> {
568
0
        self.to_os_str().map(Path::new)
569
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_path
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::to_path
570
571
    /// Lossily create a path slice from this byte string.
572
    ///
573
    /// When paths can be constructed from arbitrary byte sequences, this is
574
    /// zero cost and always returns a slice. Otherwise, this will perform a
575
    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
576
    /// the Unicode replacement codepoint.
577
    ///
578
    /// Note that this can prevent the correct roundtripping of file paths when
579
    /// the representation of `Path` is opaque.
580
    ///
581
    /// # Examples
582
    ///
583
    /// Basic usage:
584
    ///
585
    /// ```
586
    /// use bstr::ByteSlice;
587
    ///
588
    /// let bs = b"foo\xFFbar";
589
    /// let path = bs.to_path_lossy();
590
    /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
591
    /// ```
592
    #[cfg(feature = "std")]
593
    #[inline]
594
0
    fn to_path_lossy(&self) -> Cow<'_, Path> {
595
        use std::path::PathBuf;
596
597
0
        match self.to_os_str_lossy() {
598
0
            Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)),
599
0
            Cow::Owned(x) => Cow::Owned(PathBuf::from(x)),
600
        }
601
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path_lossy
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_path_lossy
602
603
    /// Create a new byte string by repeating this byte string `n` times.
604
    ///
605
    /// # Panics
606
    ///
607
    /// This function panics if the capacity of the new byte string would
608
    /// overflow.
609
    ///
610
    /// # Examples
611
    ///
612
    /// Basic usage:
613
    ///
614
    /// ```
615
    /// use bstr::{B, ByteSlice};
616
    ///
617
    /// assert_eq!(b"foo".repeatn(4), B("foofoofoofoo"));
618
    /// assert_eq!(b"foo".repeatn(0), B(""));
619
    /// ```
620
    #[cfg(feature = "alloc")]
621
    #[inline]
622
0
    fn repeatn(&self, n: usize) -> Vec<u8> {
623
0
        self.as_bytes().repeat(n)
624
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::repeatn
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::repeatn
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::repeatn
625
626
    /// Returns true if and only if this byte string contains the given needle.
627
    ///
628
    /// # Examples
629
    ///
630
    /// Basic usage:
631
    ///
632
    /// ```
633
    /// use bstr::ByteSlice;
634
    ///
635
    /// assert!(b"foo bar".contains_str("foo"));
636
    /// assert!(b"foo bar".contains_str("bar"));
637
    /// assert!(!b"foo".contains_str("foobar"));
638
    /// ```
639
    #[inline]
640
2.07M
    fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool {
641
2.07M
        self.find(needle).is_some()
642
2.07M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::contains_str::<_>
<[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&[u8]>
Line
Count
Source
640
1.64M
    fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool {
641
1.64M
        self.find(needle).is_some()
642
1.64M
    }
<[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&bstr::bstr::BStr>
Line
Count
Source
640
426k
    fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool {
641
426k
        self.find(needle).is_some()
642
426k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::contains_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::contains_str::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&[u8; 16]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&[u8; 17]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&[u8; 9]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&[u8; 15]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::contains_str::<&str>
643
644
    /// Returns true if and only if this byte string has the given prefix.
645
    ///
646
    /// # Examples
647
    ///
648
    /// Basic usage:
649
    ///
650
    /// ```
651
    /// use bstr::ByteSlice;
652
    ///
653
    /// assert!(b"foo bar".starts_with_str("foo"));
654
    /// assert!(!b"foo bar".starts_with_str("bar"));
655
    /// assert!(!b"foo".starts_with_str("foobar"));
656
    /// ```
657
    #[inline]
658
23.3k
    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659
23.3k
        self.as_bytes().starts_with(prefix.as_ref())
660
23.3k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::starts_with_str::<_>
<[u8] as bstr::ext_slice::ByteSlice>::starts_with_str::<&bstr::bstring::BString>
Line
Count
Source
658
2.01k
    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659
2.01k
        self.as_bytes().starts_with(prefix.as_ref())
660
2.01k
    }
<[u8] as bstr::ext_slice::ByteSlice>::starts_with_str::<&str>
Line
Count
Source
658
17.6k
    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659
17.6k
        self.as_bytes().starts_with(prefix.as_ref())
660
17.6k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::starts_with_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::starts_with_str::<_>
<[u8] as bstr::ext_slice::ByteSlice>::starts_with_str::<&str>
Line
Count
Source
658
2.08k
    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659
2.08k
        self.as_bytes().starts_with(prefix.as_ref())
660
2.08k
    }
<[u8] as bstr::ext_slice::ByteSlice>::starts_with_str::<&str>
Line
Count
Source
658
1.61k
    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659
1.61k
        self.as_bytes().starts_with(prefix.as_ref())
660
1.61k
    }
661
662
    /// Returns true if and only if this byte string has the given suffix.
663
    ///
664
    /// # Examples
665
    ///
666
    /// Basic usage:
667
    ///
668
    /// ```
669
    /// use bstr::ByteSlice;
670
    ///
671
    /// assert!(b"foo bar".ends_with_str("bar"));
672
    /// assert!(!b"foo bar".ends_with_str("foo"));
673
    /// assert!(!b"bar".ends_with_str("foobar"));
674
    /// ```
675
    #[inline]
676
18.9M
    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
677
18.9M
        self.as_bytes().ends_with(suffix.as_ref())
678
18.9M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::ends_with_str::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&str>
Line
Count
Source
676
18.8M
    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
677
18.8M
        self.as_bytes().ends_with(suffix.as_ref())
678
18.8M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::ends_with_str::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::ends_with_str::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&str>
Line
Count
Source
676
3.19k
    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
677
3.19k
        self.as_bytes().ends_with(suffix.as_ref())
678
3.19k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&str>
Line
Count
Source
676
1.64k
    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
677
1.64k
        self.as_bytes().ends_with(suffix.as_ref())
678
1.64k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&str>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::ends_with_str::<&[u8; 1]>
679
680
    /// Returns the index of the first occurrence of the given needle.
681
    ///
682
    /// The needle may be any type that can be cheaply converted into a
683
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
684
    ///
685
    /// Note that if you're are searching for the same needle in many
686
    /// different small haystacks, it may be faster to initialize a
687
    /// [`Finder`](struct.Finder.html) once, and reuse it for each search.
688
    ///
689
    /// # Complexity
690
    ///
691
    /// This routine is guaranteed to have worst case linear time complexity
692
    /// with respect to both the needle and the haystack. That is, this runs
693
    /// in `O(needle.len() + haystack.len())` time.
694
    ///
695
    /// This routine is also guaranteed to have worst case constant space
696
    /// complexity.
697
    ///
698
    /// # Examples
699
    ///
700
    /// Basic usage:
701
    ///
702
    /// ```
703
    /// use bstr::ByteSlice;
704
    ///
705
    /// let s = b"foo bar baz";
706
    /// assert_eq!(Some(0), s.find("foo"));
707
    /// assert_eq!(Some(4), s.find("bar"));
708
    /// assert_eq!(None, s.find("quux"));
709
    /// ```
710
    #[inline]
711
2.09M
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
2.09M
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
2.09M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find::<_>
<[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8]>
Line
Count
Source
711
1.64M
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
1.64M
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
1.64M
    }
<[u8] as bstr::ext_slice::ByteSlice>::find::<&bstr::bstr::BStr>
Line
Count
Source
711
426k
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
426k
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
426k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 16]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 17]>
<[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
Line
Count
Source
711
2.66k
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
2.66k
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
2.66k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 9]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 15]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&str>
<[u8] as bstr::ext_slice::ByteSlice>::find::<&str>
Line
Count
Source
711
10.4k
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
10.4k
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
10.4k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 4]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::find::<&str>
Line
Count
Source
711
6.25k
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
6.25k
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
6.25k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::find::<&str>
Line
Count
Source
711
4.04k
    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712
4.04k
        Finder::new(needle.as_ref()).find(self.as_bytes())
713
4.04k
    }
714
715
    /// Returns the index of the last occurrence of the given needle.
716
    ///
717
    /// The needle may be any type that can be cheaply converted into a
718
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
719
    ///
720
    /// Note that if you're are searching for the same needle in many
721
    /// different small haystacks, it may be faster to initialize a
722
    /// [`FinderReverse`](struct.FinderReverse.html) once, and reuse it for
723
    /// each search.
724
    ///
725
    /// # Complexity
726
    ///
727
    /// This routine is guaranteed to have worst case linear time complexity
728
    /// with respect to both the needle and the haystack. That is, this runs
729
    /// in `O(needle.len() + haystack.len())` time.
730
    ///
731
    /// This routine is also guaranteed to have worst case constant space
732
    /// complexity.
733
    ///
734
    /// # Examples
735
    ///
736
    /// Basic usage:
737
    ///
738
    /// ```
739
    /// use bstr::ByteSlice;
740
    ///
741
    /// let s = b"foo bar baz";
742
    /// assert_eq!(Some(0), s.rfind("foo"));
743
    /// assert_eq!(Some(4), s.rfind("bar"));
744
    /// assert_eq!(Some(8), s.rfind("ba"));
745
    /// assert_eq!(None, s.rfind("quux"));
746
    /// ```
747
    #[inline]
748
78.6k
    fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
749
78.6k
        FinderReverse::new(needle.as_ref()).rfind(self.as_bytes())
750
78.6k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind::<_>
<[u8] as bstr::ext_slice::ByteSlice>::rfind::<&[u8; 1]>
Line
Count
Source
748
71.7k
    fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
749
71.7k
        FinderReverse::new(needle.as_ref()).rfind(self.as_bytes())
750
71.7k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind::<&[u8; 1]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind::<&[u8; 1]>
<[u8] as bstr::ext_slice::ByteSlice>::rfind::<&[u8; 1]>
Line
Count
Source
748
6.92k
    fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
749
6.92k
        FinderReverse::new(needle.as_ref()).rfind(self.as_bytes())
750
6.92k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind::<&[u8; 1]>
751
752
    /// Returns an iterator of the non-overlapping occurrences of the given
753
    /// needle. The iterator yields byte offset positions indicating the start
754
    /// of each match.
755
    ///
756
    /// # Complexity
757
    ///
758
    /// This routine is guaranteed to have worst case linear time complexity
759
    /// with respect to both the needle and the haystack. That is, this runs
760
    /// in `O(needle.len() + haystack.len())` time.
761
    ///
762
    /// This routine is also guaranteed to have worst case constant space
763
    /// complexity.
764
    ///
765
    /// # Examples
766
    ///
767
    /// Basic usage:
768
    ///
769
    /// ```
770
    /// use bstr::ByteSlice;
771
    ///
772
    /// let s = b"foo bar foo foo quux foo";
773
    /// let matches: Vec<usize> = s.find_iter("foo").collect();
774
    /// assert_eq!(matches, vec![0, 8, 12, 21]);
775
    /// ```
776
    ///
777
    /// An empty string matches at every position, including the position
778
    /// immediately following the last byte:
779
    ///
780
    /// ```
781
    /// use bstr::ByteSlice;
782
    ///
783
    /// let matches: Vec<usize> = b"foo".find_iter("").collect();
784
    /// assert_eq!(matches, vec![0, 1, 2, 3]);
785
    ///
786
    /// let matches: Vec<usize> = b"".find_iter("").collect();
787
    /// assert_eq!(matches, vec![0]);
788
    /// ```
789
    #[inline]
790
2.53k
    fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
791
2.53k
        &'h self,
792
2.53k
        needle: &'n B,
793
2.53k
    ) -> Find<'h, 'n> {
794
2.53k
        Find::new(self.as_bytes(), needle.as_ref())
795
2.53k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_iter::<[u8]>
<[u8] as bstr::ext_slice::ByteSlice>::find_iter::<[u8]>
Line
Count
Source
790
2.53k
    fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
791
2.53k
        &'h self,
792
2.53k
        needle: &'n B,
793
2.53k
    ) -> Find<'h, 'n> {
794
2.53k
        Find::new(self.as_bytes(), needle.as_ref())
795
2.53k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_iter::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_iter::<[u8; 1]>
796
797
    /// Returns an iterator of the non-overlapping occurrences of the given
798
    /// needle in reverse. The iterator yields byte offset positions indicating
799
    /// the start of each match.
800
    ///
801
    /// # Complexity
802
    ///
803
    /// This routine is guaranteed to have worst case linear time complexity
804
    /// with respect to both the needle and the haystack. That is, this runs
805
    /// in `O(needle.len() + haystack.len())` time.
806
    ///
807
    /// This routine is also guaranteed to have worst case constant space
808
    /// complexity.
809
    ///
810
    /// # Examples
811
    ///
812
    /// Basic usage:
813
    ///
814
    /// ```
815
    /// use bstr::ByteSlice;
816
    ///
817
    /// let s = b"foo bar foo foo quux foo";
818
    /// let matches: Vec<usize> = s.rfind_iter("foo").collect();
819
    /// assert_eq!(matches, vec![21, 12, 8, 0]);
820
    /// ```
821
    ///
822
    /// An empty string matches at every position, including the position
823
    /// immediately following the last byte:
824
    ///
825
    /// ```
826
    /// use bstr::ByteSlice;
827
    ///
828
    /// let matches: Vec<usize> = b"foo".rfind_iter("").collect();
829
    /// assert_eq!(matches, vec![3, 2, 1, 0]);
830
    ///
831
    /// let matches: Vec<usize> = b"".rfind_iter("").collect();
832
    /// assert_eq!(matches, vec![0]);
833
    /// ```
834
    #[inline]
835
0
    fn rfind_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
836
0
        &'h self,
837
0
        needle: &'n B,
838
0
    ) -> FindReverse<'h, 'n> {
839
0
        FindReverse::new(self.as_bytes(), needle.as_ref())
840
0
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_iter::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_iter::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_iter::<[u8]>
841
842
    /// Returns the index of the first occurrence of the given byte. If the
843
    /// byte does not occur in this byte string, then `None` is returned.
844
    ///
845
    /// # Examples
846
    ///
847
    /// Basic usage:
848
    ///
849
    /// ```
850
    /// use bstr::ByteSlice;
851
    ///
852
    /// assert_eq!(Some(10), b"foo bar baz".find_byte(b'z'));
853
    /// assert_eq!(None, b"foo bar baz".find_byte(b'y'));
854
    /// ```
855
    #[inline]
856
664M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
664M
        memchr(byte, self.as_bytes())
858
664M
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
7.37M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
7.37M
        memchr(byte, self.as_bytes())
858
7.37M
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
104k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
104k
        memchr(byte, self.as_bytes())
858
104k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
46.2M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
46.2M
        memchr(byte, self.as_bytes())
858
46.2M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
6.57M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
6.57M
        memchr(byte, self.as_bytes())
858
6.57M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
147k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
147k
        memchr(byte, self.as_bytes())
858
147k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
1.42M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
1.42M
        memchr(byte, self.as_bytes())
858
1.42M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
211M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
211M
        memchr(byte, self.as_bytes())
858
211M
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
3.34k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
3.34k
        memchr(byte, self.as_bytes())
858
3.34k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
9.83M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
9.83M
        memchr(byte, self.as_bytes())
858
9.83M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
19.7k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
19.7k
        memchr(byte, self.as_bytes())
858
19.7k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
4.86k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
4.86k
        memchr(byte, self.as_bytes())
858
4.86k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
5.51k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
5.51k
        memchr(byte, self.as_bytes())
858
5.51k
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
64.9k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
64.9k
        memchr(byte, self.as_bytes())
858
64.9k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
377M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
377M
        memchr(byte, self.as_bytes())
858
377M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
33.7k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
33.7k
        memchr(byte, self.as_bytes())
858
33.7k
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
2.42k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
2.42k
        memchr(byte, self.as_bytes())
858
2.42k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
4.89k
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
4.89k
        memchr(byte, self.as_bytes())
858
4.89k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
<[u8] as bstr::ext_slice::ByteSlice>::find_byte
Line
Count
Source
856
3.70M
    fn find_byte(&self, byte: u8) -> Option<usize> {
857
3.70M
        memchr(byte, self.as_bytes())
858
3.70M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byte
859
860
    /// Returns the index of the last occurrence of the given byte. If the
861
    /// byte does not occur in this byte string, then `None` is returned.
862
    ///
863
    /// # Examples
864
    ///
865
    /// Basic usage:
866
    ///
867
    /// ```
868
    /// use bstr::ByteSlice;
869
    ///
870
    /// assert_eq!(Some(10), b"foo bar baz".rfind_byte(b'z'));
871
    /// assert_eq!(None, b"foo bar baz".rfind_byte(b'y'));
872
    /// ```
873
    #[inline]
874
1.56M
    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875
1.56M
        memrchr(byte, self.as_bytes())
876
1.56M
    }
<[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Line
Count
Source
874
53.3k
    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875
53.3k
        memrchr(byte, self.as_bytes())
876
53.3k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
<[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Line
Count
Source
874
76.3k
    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875
76.3k
        memrchr(byte, self.as_bytes())
876
76.3k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
<[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Line
Count
Source
874
1.42M
    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875
1.42M
        memrchr(byte, self.as_bytes())
876
1.42M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
<[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Line
Count
Source
874
6.94k
    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875
6.94k
        memrchr(byte, self.as_bytes())
876
6.94k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byte
877
878
    /// Returns the index of the first occurrence of the given codepoint.
879
    /// If the codepoint does not occur in this byte string, then `None` is
880
    /// returned.
881
    ///
882
    /// Note that if one searches for the replacement codepoint, `\u{FFFD}`,
883
    /// then only explicit occurrences of that encoding will be found. Invalid
884
    /// UTF-8 sequences will not be matched.
885
    ///
886
    /// # Examples
887
    ///
888
    /// Basic usage:
889
    ///
890
    /// ```
891
    /// use bstr::{B, ByteSlice};
892
    ///
893
    /// assert_eq!(Some(10), b"foo bar baz".find_char('z'));
894
    /// assert_eq!(Some(4), B("αβγγδ").find_char('γ'));
895
    /// assert_eq!(None, b"foo bar baz".find_char('y'));
896
    /// ```
897
    #[inline]
898
0
    fn find_char(&self, ch: char) -> Option<usize> {
899
0
        self.find(ch.encode_utf8(&mut [0; 4]))
900
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_char
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_char
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_char
901
902
    /// Returns the index of the last occurrence of the given codepoint.
903
    /// If the codepoint does not occur in this byte string, then `None` is
904
    /// returned.
905
    ///
906
    /// Note that if one searches for the replacement codepoint, `\u{FFFD}`,
907
    /// then only explicit occurrences of that encoding will be found. Invalid
908
    /// UTF-8 sequences will not be matched.
909
    ///
910
    /// # Examples
911
    ///
912
    /// Basic usage:
913
    ///
914
    /// ```
915
    /// use bstr::{B, ByteSlice};
916
    ///
917
    /// assert_eq!(Some(10), b"foo bar baz".rfind_char('z'));
918
    /// assert_eq!(Some(6), B("αβγγδ").rfind_char('γ'));
919
    /// assert_eq!(None, b"foo bar baz".rfind_char('y'));
920
    /// ```
921
    #[inline]
922
0
    fn rfind_char(&self, ch: char) -> Option<usize> {
923
0
        self.rfind(ch.encode_utf8(&mut [0; 4]))
924
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_char
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_char
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_char
925
926
    /// Returns the index of the first occurrence of any of the bytes in the
927
    /// provided set.
928
    ///
929
    /// The `byteset` may be any type that can be cheaply converted into a
930
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
931
    /// note that passing a `&str` which contains multibyte characters may not
932
    /// behave as you expect: each byte in the `&str` is treated as an
933
    /// individual member of the byte set.
934
    ///
935
    /// Note that order is irrelevant for the `byteset` parameter, and
936
    /// duplicate bytes present in its body are ignored.
937
    ///
938
    /// # Complexity
939
    ///
940
    /// This routine is guaranteed to have worst case linear time complexity
941
    /// with respect to both the set of bytes and the haystack. That is, this
942
    /// runs in `O(byteset.len() + haystack.len())` time.
943
    ///
944
    /// This routine is also guaranteed to have worst case constant space
945
    /// complexity.
946
    ///
947
    /// # Examples
948
    ///
949
    /// Basic usage:
950
    ///
951
    /// ```
952
    /// use bstr::ByteSlice;
953
    ///
954
    /// assert_eq!(b"foo bar baz".find_byteset(b"zr"), Some(6));
955
    /// assert_eq!(b"foo baz bar".find_byteset(b"bzr"), Some(4));
956
    /// assert_eq!(None, b"foo baz bar".find_byteset(b"\t\n"));
957
    /// // The empty byteset never matches.
958
    /// assert_eq!(None, b"abc".find_byteset(b""));
959
    /// assert_eq!(None, b"".find_byteset(b""));
960
    /// ```
961
    #[inline]
962
23.3M
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
23.3M
        byteset::find(self.as_bytes(), byteset.as_ref())
964
23.3M
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 3]>
Line
Count
Source
962
9.34k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
9.34k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
9.34k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byteset::<_>
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Line
Count
Source
962
17.0M
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
17.0M
        byteset::find(self.as_bytes(), byteset.as_ref())
964
17.0M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 3]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_byteset::<_>
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Line
Count
Source
962
6.25M
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
6.25M
        byteset::find(self.as_bytes(), byteset.as_ref())
964
6.25M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 17]>
Line
Count
Source
962
1.01k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
1.01k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
1.01k
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 22]>
Line
Count
Source
962
3.29k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
3.29k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
3.29k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 4]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 17]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 22]>
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Line
Count
Source
962
9.51k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
9.51k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
9.51k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 17]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 22]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Line
Count
Source
962
14.5k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
14.5k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
14.5k
    }
<[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Line
Count
Source
962
19.6k
    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963
19.6k
        byteset::find(self.as_bytes(), byteset.as_ref())
964
19.6k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_byteset::<&[u8]>
965
966
    /// Returns the index of the first occurrence of a byte that is not a
967
    /// member of the provided set.
968
    ///
969
    /// The `byteset` may be any type that can be cheaply converted into a
970
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
971
    /// note that passing a `&str` which contains multibyte characters may not
972
    /// behave as you expect: each byte in the `&str` is treated as an
973
    /// individual member of the byte set.
974
    ///
975
    /// Note that order is irrelevant for the `byteset` parameter, and
976
    /// duplicate bytes present in its body are ignored.
977
    ///
978
    /// # Complexity
979
    ///
980
    /// This routine is guaranteed to have worst case linear time complexity
981
    /// with respect to both the set of bytes and the haystack. That is, this
982
    /// runs in `O(byteset.len() + haystack.len())` time.
983
    ///
984
    /// This routine is also guaranteed to have worst case constant space
985
    /// complexity.
986
    ///
987
    /// # Examples
988
    ///
989
    /// Basic usage:
990
    ///
991
    /// ```
992
    /// use bstr::ByteSlice;
993
    ///
994
    /// assert_eq!(b"foo bar baz".find_not_byteset(b"fo "), Some(4));
995
    /// assert_eq!(b"\t\tbaz bar".find_not_byteset(b" \t\r\n"), Some(2));
996
    /// assert_eq!(b"foo\nbaz\tbar".find_not_byteset(b"\t\n"), Some(0));
997
    /// // The negation of the empty byteset matches everything.
998
    /// assert_eq!(Some(0), b"abc".find_not_byteset(b""));
999
    /// // But an empty string never contains anything.
1000
    /// assert_eq!(None, b"".find_not_byteset(b""));
1001
    /// ```
1002
    #[inline]
1003
26.8k
    fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1004
26.8k
        byteset::find_not(self.as_bytes(), byteset.as_ref())
1005
26.8k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_not_byteset::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_not_byteset::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_not_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_not_byteset::<&[u8]>
<[u8] as bstr::ext_slice::ByteSlice>::find_not_byteset::<&[u8]>
Line
Count
Source
1003
26.8k
    fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1004
26.8k
        byteset::find_not(self.as_bytes(), byteset.as_ref())
1005
26.8k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::find_not_byteset::<&[u8]>
1006
1007
    /// Returns the index of the last occurrence of any of the bytes in the
1008
    /// provided set.
1009
    ///
1010
    /// The `byteset` may be any type that can be cheaply converted into a
1011
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
1012
    /// note that passing a `&str` which contains multibyte characters may not
1013
    /// behave as you expect: each byte in the `&str` is treated as an
1014
    /// individual member of the byte set.
1015
    ///
1016
    /// Note that order is irrelevant for the `byteset` parameter, and duplicate
1017
    /// bytes present in its body are ignored.
1018
    ///
1019
    /// # Complexity
1020
    ///
1021
    /// This routine is guaranteed to have worst case linear time complexity
1022
    /// with respect to both the set of bytes and the haystack. That is, this
1023
    /// runs in `O(byteset.len() + haystack.len())` time.
1024
    ///
1025
    /// This routine is also guaranteed to have worst case constant space
1026
    /// complexity.
1027
    ///
1028
    /// # Examples
1029
    ///
1030
    /// Basic usage:
1031
    ///
1032
    /// ```
1033
    /// use bstr::ByteSlice;
1034
    ///
1035
    /// assert_eq!(b"foo bar baz".rfind_byteset(b"agb"), Some(9));
1036
    /// assert_eq!(b"foo baz bar".rfind_byteset(b"rabz "), Some(10));
1037
    /// assert_eq!(b"foo baz bar".rfind_byteset(b"\n123"), None);
1038
    /// ```
1039
    #[inline]
1040
0
    fn rfind_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1041
0
        byteset::rfind(self.as_bytes(), byteset.as_ref())
1042
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byteset::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byteset::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byteset::<&[u8; 2]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_byteset::<&[u8; 2]>
1043
1044
    /// Returns the index of the last occurrence of a byte that is not a member
1045
    /// of the provided set.
1046
    ///
1047
    /// The `byteset` may be any type that can be cheaply converted into a
1048
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
1049
    /// note that passing a `&str` which contains multibyte characters may not
1050
    /// behave as you expect: each byte in the `&str` is treated as an
1051
    /// individual member of the byte set.
1052
    ///
1053
    /// Note that order is irrelevant for the `byteset` parameter, and
1054
    /// duplicate bytes present in its body are ignored.
1055
    ///
1056
    /// # Complexity
1057
    ///
1058
    /// This routine is guaranteed to have worst case linear time complexity
1059
    /// with respect to both the set of bytes and the haystack. That is, this
1060
    /// runs in `O(byteset.len() + haystack.len())` time.
1061
    ///
1062
    /// This routine is also guaranteed to have worst case constant space
1063
    /// complexity.
1064
    ///
1065
    /// # Examples
1066
    ///
1067
    /// Basic usage:
1068
    ///
1069
    /// ```
1070
    /// use bstr::ByteSlice;
1071
    ///
1072
    /// assert_eq!(b"foo bar baz,\t".rfind_not_byteset(b",\t"), Some(10));
1073
    /// assert_eq!(b"foo baz bar".rfind_not_byteset(b"rabz "), Some(2));
1074
    /// assert_eq!(None, b"foo baz bar".rfind_not_byteset(b"barfoz "));
1075
    /// ```
1076
    #[inline]
1077
0
    fn rfind_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1078
0
        byteset::rfind_not(self.as_bytes(), byteset.as_ref())
1079
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<_>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rfind_not_byteset::<&[u8; 5]>
1080
1081
    /// Returns an iterator over the fields in a byte string, separated
1082
    /// by contiguous whitespace (according to the Unicode property
1083
    /// `White_Space`).
1084
    ///
1085
    /// # Example
1086
    ///
1087
    /// Basic usage:
1088
    ///
1089
    /// ```
1090
    /// use bstr::{B, ByteSlice};
1091
    ///
1092
    /// let s = B("  foo\tbar\t\u{2003}\nquux   \n");
1093
    /// let fields: Vec<&[u8]> = s.fields().collect();
1094
    /// assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
1095
    /// ```
1096
    ///
1097
    /// A byte string consisting of just whitespace yields no elements:
1098
    ///
1099
    /// ```
1100
    /// use bstr::{B, ByteSlice};
1101
    ///
1102
    /// assert_eq!(0, B("  \n\t\u{2003}\n  \t").fields().count());
1103
    /// ```
1104
    #[cfg(feature = "unicode")]
1105
    #[doc(alias = "split_whitespace")]
1106
    #[inline]
1107
19.1k
    fn fields(&self) -> Fields<'_> {
1108
19.1k
        Fields::new(self.as_bytes())
1109
19.1k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::fields
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::fields
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::fields
<[u8] as bstr::ext_slice::ByteSlice>::fields
Line
Count
Source
1107
15.4k
    fn fields(&self) -> Fields<'_> {
1108
15.4k
        Fields::new(self.as_bytes())
1109
15.4k
    }
<[u8] as bstr::ext_slice::ByteSlice>::fields
Line
Count
Source
1107
3.75k
    fn fields(&self) -> Fields<'_> {
1108
3.75k
        Fields::new(self.as_bytes())
1109
3.75k
    }
1110
1111
    /// Returns an iterator over the fields in a byte string, separated by
1112
    /// contiguous codepoints satisfying the given predicate.
1113
    ///
1114
    /// If this byte string is not valid UTF-8, then the given closure will
1115
    /// be called with a Unicode replacement codepoint when invalid UTF-8
1116
    /// bytes are seen.
1117
    ///
1118
    /// # Example
1119
    ///
1120
    /// Basic usage:
1121
    ///
1122
    /// ```
1123
    /// use bstr::{B, ByteSlice};
1124
    ///
1125
    /// let s = b"123foo999999bar1quux123456";
1126
    /// let fields: Vec<&[u8]> = s.fields_with(|c| c.is_numeric()).collect();
1127
    /// assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
1128
    /// ```
1129
    ///
1130
    /// A byte string consisting of all codepoints satisfying the predicate
1131
    /// yields no elements:
1132
    ///
1133
    /// ```
1134
    /// use bstr::ByteSlice;
1135
    ///
1136
    /// assert_eq!(0, b"1911354563".fields_with(|c| c.is_numeric()).count());
1137
    /// ```
1138
    #[inline]
1139
19.1k
    fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F> {
1140
19.1k
        FieldsWith::new(self.as_bytes(), f)
1141
19.1k
    }
<[u8] as bstr::ext_slice::ByteSlice>::fields_with::<fn(char) -> bool>
Line
Count
Source
1139
19.1k
    fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F> {
1140
19.1k
        FieldsWith::new(self.as_bytes(), f)
1141
19.1k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::fields_with::<fn(char) -> bool>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::fields_with::<_>
1142
1143
    /// Returns an iterator over substrings of this byte string, separated
1144
    /// by the given byte string. Each element yielded is guaranteed not to
1145
    /// include the splitter substring.
1146
    ///
1147
    /// The splitter may be any type that can be cheaply converted into a
1148
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1149
    ///
1150
    /// # Examples
1151
    ///
1152
    /// Basic usage:
1153
    ///
1154
    /// ```
1155
    /// use bstr::{B, ByteSlice};
1156
    ///
1157
    /// let x: Vec<&[u8]> = b"Mary had a little lamb".split_str(" ").collect();
1158
    /// assert_eq!(x, vec![
1159
    ///     B("Mary"), B("had"), B("a"), B("little"), B("lamb"),
1160
    /// ]);
1161
    ///
1162
    /// let x: Vec<&[u8]> = b"".split_str("X").collect();
1163
    /// assert_eq!(x, vec![b""]);
1164
    ///
1165
    /// let x: Vec<&[u8]> = b"lionXXtigerXleopard".split_str("X").collect();
1166
    /// assert_eq!(x, vec![B("lion"), B(""), B("tiger"), B("leopard")]);
1167
    ///
1168
    /// let x: Vec<&[u8]> = b"lion::tiger::leopard".split_str("::").collect();
1169
    /// assert_eq!(x, vec![B("lion"), B("tiger"), B("leopard")]);
1170
    /// ```
1171
    ///
1172
    /// If a string contains multiple contiguous separators, you will end up
1173
    /// with empty strings yielded by the iterator:
1174
    ///
1175
    /// ```
1176
    /// use bstr::{B, ByteSlice};
1177
    ///
1178
    /// let x: Vec<&[u8]> = b"||||a||b|c".split_str("|").collect();
1179
    /// assert_eq!(x, vec![
1180
    ///     B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
1181
    /// ]);
1182
    ///
1183
    /// let x: Vec<&[u8]> = b"(///)".split_str("/").collect();
1184
    /// assert_eq!(x, vec![B("("), B(""), B(""), B(")")]);
1185
    /// ```
1186
    ///
1187
    /// Separators at the start or end of a string are neighbored by empty
1188
    /// strings.
1189
    ///
1190
    /// ```
1191
    /// use bstr::{B, ByteSlice};
1192
    ///
1193
    /// let x: Vec<&[u8]> = b"010".split_str("0").collect();
1194
    /// assert_eq!(x, vec![B(""), B("1"), B("")]);
1195
    /// ```
1196
    ///
1197
    /// When the empty string is used as a separator, it splits every **byte**
1198
    /// in the byte string, along with the beginning and end of the byte
1199
    /// string.
1200
    ///
1201
    /// ```
1202
    /// use bstr::{B, ByteSlice};
1203
    ///
1204
    /// let x: Vec<&[u8]> = b"rust".split_str("").collect();
1205
    /// assert_eq!(x, vec![
1206
    ///     B(""), B("r"), B("u"), B("s"), B("t"), B(""),
1207
    /// ]);
1208
    ///
1209
    /// // Splitting by an empty string is not UTF-8 aware. Elements yielded
1210
    /// // may not be valid UTF-8!
1211
    /// let x: Vec<&[u8]> = B("☃").split_str("").collect();
1212
    /// assert_eq!(x, vec![
1213
    ///     B(""), B(b"\xE2"), B(b"\x98"), B(b"\x83"), B(""),
1214
    /// ]);
1215
    /// ```
1216
    ///
1217
    /// Contiguous separators, especially whitespace, can lead to possibly
1218
    /// surprising behavior. For example, this code is correct:
1219
    ///
1220
    /// ```
1221
    /// use bstr::{B, ByteSlice};
1222
    ///
1223
    /// let x: Vec<&[u8]> = b"    a  b c".split_str(" ").collect();
1224
    /// assert_eq!(x, vec![
1225
    ///     B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
1226
    /// ]);
1227
    /// ```
1228
    ///
1229
    /// It does *not* give you `["a", "b", "c"]`. For that behavior, use
1230
    /// [`fields`](#method.fields) instead.
1231
    #[inline]
1232
2.53k
    fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1233
2.53k
        &'h self,
1234
2.53k
        splitter: &'s B,
1235
2.53k
    ) -> Split<'h, 's> {
1236
2.53k
        Split::new(self.as_bytes(), splitter.as_ref())
1237
2.53k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::split_str::<[u8]>
<[u8] as bstr::ext_slice::ByteSlice>::split_str::<[u8; 1]>
Line
Count
Source
1232
1.53k
    fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1233
1.53k
        &'h self,
1234
1.53k
        splitter: &'s B,
1235
1.53k
    ) -> Split<'h, 's> {
1236
1.53k
        Split::new(self.as_bytes(), splitter.as_ref())
1237
1.53k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::split_str::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::split_str::<[u8]>
<[u8] as bstr::ext_slice::ByteSlice>::split_str::<[u8; 1]>
Line
Count
Source
1232
1.00k
    fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1233
1.00k
        &'h self,
1234
1.00k
        splitter: &'s B,
1235
1.00k
    ) -> Split<'h, 's> {
1236
1.00k
        Split::new(self.as_bytes(), splitter.as_ref())
1237
1.00k
    }
1238
1239
    /// Returns an iterator over substrings of this byte string, separated by
1240
    /// the given byte string, in reverse. Each element yielded is guaranteed
1241
    /// not to include the splitter substring.
1242
    ///
1243
    /// The splitter may be any type that can be cheaply converted into a
1244
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1245
    ///
1246
    /// # Examples
1247
    ///
1248
    /// Basic usage:
1249
    ///
1250
    /// ```
1251
    /// use bstr::{B, ByteSlice};
1252
    ///
1253
    /// let x: Vec<&[u8]> =
1254
    ///     b"Mary had a little lamb".rsplit_str(" ").collect();
1255
    /// assert_eq!(x, vec![
1256
    ///     B("lamb"), B("little"), B("a"), B("had"), B("Mary"),
1257
    /// ]);
1258
    ///
1259
    /// let x: Vec<&[u8]> = b"".rsplit_str("X").collect();
1260
    /// assert_eq!(x, vec![b""]);
1261
    ///
1262
    /// let x: Vec<&[u8]> = b"lionXXtigerXleopard".rsplit_str("X").collect();
1263
    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B(""), B("lion")]);
1264
    ///
1265
    /// let x: Vec<&[u8]> = b"lion::tiger::leopard".rsplit_str("::").collect();
1266
    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B("lion")]);
1267
    /// ```
1268
    ///
1269
    /// If a string contains multiple contiguous separators, you will end up
1270
    /// with empty strings yielded by the iterator:
1271
    ///
1272
    /// ```
1273
    /// use bstr::{B, ByteSlice};
1274
    ///
1275
    /// let x: Vec<&[u8]> = b"||||a||b|c".rsplit_str("|").collect();
1276
    /// assert_eq!(x, vec![
1277
    ///     B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
1278
    /// ]);
1279
    ///
1280
    /// let x: Vec<&[u8]> = b"(///)".rsplit_str("/").collect();
1281
    /// assert_eq!(x, vec![B(")"), B(""), B(""), B("(")]);
1282
    /// ```
1283
    ///
1284
    /// Separators at the start or end of a string are neighbored by empty
1285
    /// strings.
1286
    ///
1287
    /// ```
1288
    /// use bstr::{B, ByteSlice};
1289
    ///
1290
    /// let x: Vec<&[u8]> = b"010".rsplit_str("0").collect();
1291
    /// assert_eq!(x, vec![B(""), B("1"), B("")]);
1292
    /// ```
1293
    ///
1294
    /// When the empty string is used as a separator, it splits every **byte**
1295
    /// in the byte string, along with the beginning and end of the byte
1296
    /// string.
1297
    ///
1298
    /// ```
1299
    /// use bstr::{B, ByteSlice};
1300
    ///
1301
    /// let x: Vec<&[u8]> = b"rust".rsplit_str("").collect();
1302
    /// assert_eq!(x, vec![
1303
    ///     B(""), B("t"), B("s"), B("u"), B("r"), B(""),
1304
    /// ]);
1305
    ///
1306
    /// // Splitting by an empty string is not UTF-8 aware. Elements yielded
1307
    /// // may not be valid UTF-8!
1308
    /// let x: Vec<&[u8]> = B("☃").rsplit_str("").collect();
1309
    /// assert_eq!(x, vec![B(""), B(b"\x83"), B(b"\x98"), B(b"\xE2"), B("")]);
1310
    /// ```
1311
    ///
1312
    /// Contiguous separators, especially whitespace, can lead to possibly
1313
    /// surprising behavior. For example, this code is correct:
1314
    ///
1315
    /// ```
1316
    /// use bstr::{B, ByteSlice};
1317
    ///
1318
    /// let x: Vec<&[u8]> = b"    a  b c".rsplit_str(" ").collect();
1319
    /// assert_eq!(x, vec![
1320
    ///     B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
1321
    /// ]);
1322
    /// ```
1323
    ///
1324
    /// It does *not* give you `["a", "b", "c"]`.
1325
    #[inline]
1326
0
    fn rsplit_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1327
0
        &'h self,
1328
0
        splitter: &'s B,
1329
0
    ) -> SplitReverse<'h, 's> {
1330
0
        SplitReverse::new(self.as_bytes(), splitter.as_ref())
1331
0
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rsplit_str::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rsplit_str::<[u8]>
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::rsplit_str::<[u8]>
1332
1333
    /// Split this byte string at the first occurrence of `splitter`.
1334
    ///
1335
    /// If the `splitter` is found in the byte string, returns a tuple
1336
    /// containing the parts of the string before and after the first occurrence
1337
    /// of `splitter` respectively. Otherwise, if there are no occurrences of
1338
    /// `splitter` in the byte string, returns `None`.
1339
    ///
1340
    /// The splitter may be any type that can be cheaply converted into a
1341
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1342
    ///
1343
    /// If you need to split on the *last* instance of a delimiter instead, see
1344
    /// the [`ByteSlice::rsplit_once_str`](#method.rsplit_once_str) method .
1345
    ///
1346
    /// # Examples
1347
    ///
1348
    /// Basic usage:
1349
    ///
1350
    /// ```
1351
    /// use bstr::{B, ByteSlice};
1352
    ///
1353
    /// assert_eq!(
1354
    ///     B("foo,bar").split_once_str(","),
1355
    ///     Some((B("foo"), B("bar"))),
1356
    /// );
1357
    /// assert_eq!(
1358
    ///     B("foo,bar,baz").split_once_str(","),
1359
    ///     Some((B("foo"), B("bar,baz"))),
1360
    /// );
1361
    /// assert_eq!(B("foo").split_once_str(","), None);
1362
    /// assert_eq!(B("foo,").split_once_str(b","), Some((B("foo"), B(""))));
1363
    /// assert_eq!(B(",foo").split_once_str(b","), Some((B(""), B("foo"))));
1364
    /// ```
1365
    #[inline]
1366
0
    fn split_once_str<'a, B: ?Sized + AsRef<[u8]>>(
1367
0
        &'a self,
1368
0
        splitter: &B,
1369
0
    ) -> Option<(&'a [u8], &'a [u8])> {
1370
0
        let bytes = self.as_bytes();
1371
0
        let splitter = splitter.as_ref();
1372
0
        let start = Finder::new(splitter).find(bytes)?;
1373
0
        let end = start + splitter.len();
1374
0
        Some((&bytes[..start], &bytes[end..]))
1375
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::split_once_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::split_once_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::split_once_str::<_>
1376
1377
    /// Split this byte string at the last occurrence of `splitter`.
1378
    ///
1379
    /// If the `splitter` is found in the byte string, returns a tuple
1380
    /// containing the parts of the string before and after the last occurrence
1381
    /// of `splitter`, respectively. Otherwise, if there are no occurrences of
1382
    /// `splitter` in the byte string, returns `None`.
1383
    ///
1384
    /// The splitter may be any type that can be cheaply converted into a
1385
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1386
    ///
1387
    /// If you need to split on the *first* instance of a delimiter instead, see
1388
    /// the [`ByteSlice::split_once_str`](#method.split_once_str) method.
1389
    ///
1390
    /// # Examples
1391
    ///
1392
    /// Basic usage:
1393
    ///
1394
    /// ```
1395
    /// use bstr::{B, ByteSlice};
1396
    ///
1397
    /// assert_eq!(
1398
    ///     B("foo,bar").rsplit_once_str(","),
1399
    ///     Some((B("foo"), B("bar"))),
1400
    /// );
1401
    /// assert_eq!(
1402
    ///     B("foo,bar,baz").rsplit_once_str(","),
1403
    ///     Some((B("foo,bar"), B("baz"))),
1404
    /// );
1405
    /// assert_eq!(B("foo").rsplit_once_str(","), None);
1406
    /// assert_eq!(B("foo,").rsplit_once_str(b","), Some((B("foo"), B(""))));
1407
    /// assert_eq!(B(",foo").rsplit_once_str(b","), Some((B(""), B("foo"))));
1408
    /// ```
1409
    #[inline]
1410
0
    fn rsplit_once_str<'a, B: ?Sized + AsRef<[u8]>>(
1411
0
        &'a self,
1412
0
        splitter: &B,
1413
0
    ) -> Option<(&'a [u8], &'a [u8])> {
1414
0
        let bytes = self.as_bytes();
1415
0
        let splitter = splitter.as_ref();
1416
0
        let start = FinderReverse::new(splitter).rfind(bytes)?;
1417
0
        let end = start + splitter.len();
1418
0
        Some((&bytes[..start], &bytes[end..]))
1419
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplit_once_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplit_once_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplit_once_str::<_>
1420
1421
    /// Returns an iterator of at most `limit` substrings of this byte string,
1422
    /// separated by the given byte string. If `limit` substrings are yielded,
1423
    /// then the last substring will contain the remainder of this byte string.
1424
    ///
1425
    /// The needle may be any type that can be cheaply converted into a
1426
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1427
    ///
1428
    /// # Examples
1429
    ///
1430
    /// Basic usage:
1431
    ///
1432
    /// ```
1433
    /// use bstr::{B, ByteSlice};
1434
    ///
1435
    /// let x: Vec<_> = b"Mary had a little lamb".splitn_str(3, " ").collect();
1436
    /// assert_eq!(x, vec![B("Mary"), B("had"), B("a little lamb")]);
1437
    ///
1438
    /// let x: Vec<_> = b"".splitn_str(3, "X").collect();
1439
    /// assert_eq!(x, vec![b""]);
1440
    ///
1441
    /// let x: Vec<_> = b"lionXXtigerXleopard".splitn_str(3, "X").collect();
1442
    /// assert_eq!(x, vec![B("lion"), B(""), B("tigerXleopard")]);
1443
    ///
1444
    /// let x: Vec<_> = b"lion::tiger::leopard".splitn_str(2, "::").collect();
1445
    /// assert_eq!(x, vec![B("lion"), B("tiger::leopard")]);
1446
    ///
1447
    /// let x: Vec<_> = b"abcXdef".splitn_str(1, "X").collect();
1448
    /// assert_eq!(x, vec![B("abcXdef")]);
1449
    ///
1450
    /// let x: Vec<_> = b"abcdef".splitn_str(2, "X").collect();
1451
    /// assert_eq!(x, vec![B("abcdef")]);
1452
    ///
1453
    /// let x: Vec<_> = b"abcXdef".splitn_str(0, "X").collect();
1454
    /// assert!(x.is_empty());
1455
    /// ```
1456
    #[inline]
1457
0
    fn splitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1458
0
        &'h self,
1459
0
        limit: usize,
1460
0
        splitter: &'s B,
1461
0
    ) -> SplitN<'h, 's> {
1462
0
        SplitN::new(self.as_bytes(), splitter.as_ref(), limit)
1463
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::splitn_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::splitn_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::splitn_str::<_>
1464
1465
    /// Returns an iterator of at most `limit` substrings of this byte string,
1466
    /// separated by the given byte string, in reverse. If `limit` substrings
1467
    /// are yielded, then the last substring will contain the remainder of this
1468
    /// byte string.
1469
    ///
1470
    /// The needle may be any type that can be cheaply converted into a
1471
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
1472
    ///
1473
    /// # Examples
1474
    ///
1475
    /// Basic usage:
1476
    ///
1477
    /// ```
1478
    /// use bstr::{B, ByteSlice};
1479
    ///
1480
    /// let x: Vec<_> =
1481
    ///     b"Mary had a little lamb".rsplitn_str(3, " ").collect();
1482
    /// assert_eq!(x, vec![B("lamb"), B("little"), B("Mary had a")]);
1483
    ///
1484
    /// let x: Vec<_> = b"".rsplitn_str(3, "X").collect();
1485
    /// assert_eq!(x, vec![b""]);
1486
    ///
1487
    /// let x: Vec<_> = b"lionXXtigerXleopard".rsplitn_str(3, "X").collect();
1488
    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B("lionX")]);
1489
    ///
1490
    /// let x: Vec<_> = b"lion::tiger::leopard".rsplitn_str(2, "::").collect();
1491
    /// assert_eq!(x, vec![B("leopard"), B("lion::tiger")]);
1492
    ///
1493
    /// let x: Vec<_> = b"abcXdef".rsplitn_str(1, "X").collect();
1494
    /// assert_eq!(x, vec![B("abcXdef")]);
1495
    ///
1496
    /// let x: Vec<_> = b"abcdef".rsplitn_str(2, "X").collect();
1497
    /// assert_eq!(x, vec![B("abcdef")]);
1498
    ///
1499
    /// let x: Vec<_> = b"abcXdef".rsplitn_str(0, "X").collect();
1500
    /// assert!(x.is_empty());
1501
    /// ```
1502
    #[inline]
1503
0
    fn rsplitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1504
0
        &'h self,
1505
0
        limit: usize,
1506
0
        splitter: &'s B,
1507
0
    ) -> SplitNReverse<'h, 's> {
1508
0
        SplitNReverse::new(self.as_bytes(), splitter.as_ref(), limit)
1509
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplitn_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplitn_str::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::rsplitn_str::<_>
1510
1511
    /// Replace all matches of the given needle with the given replacement, and
1512
    /// the result as a new `Vec<u8>`.
1513
    ///
1514
    /// This routine is useful as a convenience. If you need to reuse an
1515
    /// allocation, use [`replace_into`](#method.replace_into) instead.
1516
    ///
1517
    /// # Examples
1518
    ///
1519
    /// Basic usage:
1520
    ///
1521
    /// ```
1522
    /// use bstr::ByteSlice;
1523
    ///
1524
    /// let s = b"this is old".replace("old", "new");
1525
    /// assert_eq!(s, "this is new".as_bytes());
1526
    /// ```
1527
    ///
1528
    /// When the pattern doesn't match:
1529
    ///
1530
    /// ```
1531
    /// use bstr::ByteSlice;
1532
    ///
1533
    /// let s = b"this is old".replace("nada nada", "limonada");
1534
    /// assert_eq!(s, "this is old".as_bytes());
1535
    /// ```
1536
    ///
1537
    /// When the needle is an empty string:
1538
    ///
1539
    /// ```
1540
    /// use bstr::ByteSlice;
1541
    ///
1542
    /// let s = b"foo".replace("", "Z");
1543
    /// assert_eq!(s, "ZfZoZoZ".as_bytes());
1544
    /// ```
1545
    #[cfg(feature = "alloc")]
1546
    #[must_use]
1547
    #[inline]
1548
0
    fn replace<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1549
0
        &self,
1550
0
        needle: N,
1551
0
        replacement: R,
1552
0
    ) -> Vec<u8> {
1553
0
        let mut dest = Vec::with_capacity(self.as_bytes().len());
1554
0
        self.replace_into(needle, replacement, &mut dest);
1555
0
        dest
1556
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace::<_, _>
1557
1558
    /// Replace up to `limit` matches of the given needle with the given
1559
    /// replacement, and the result as a new `Vec<u8>`.
1560
    ///
1561
    /// This routine is useful as a convenience. If you need to reuse an
1562
    /// allocation, use [`replacen_into`](#method.replacen_into) instead.
1563
    ///
1564
    /// # Examples
1565
    ///
1566
    /// Basic usage:
1567
    ///
1568
    /// ```
1569
    /// use bstr::ByteSlice;
1570
    ///
1571
    /// let s = b"foofoo".replacen("o", "z", 2);
1572
    /// assert_eq!(s, "fzzfoo".as_bytes());
1573
    /// ```
1574
    ///
1575
    /// When the pattern doesn't match:
1576
    ///
1577
    /// ```
1578
    /// use bstr::ByteSlice;
1579
    ///
1580
    /// let s = b"foofoo".replacen("a", "z", 2);
1581
    /// assert_eq!(s, "foofoo".as_bytes());
1582
    /// ```
1583
    ///
1584
    /// When the needle is an empty string:
1585
    ///
1586
    /// ```
1587
    /// use bstr::ByteSlice;
1588
    ///
1589
    /// let s = b"foo".replacen("", "Z", 2);
1590
    /// assert_eq!(s, "ZfZoo".as_bytes());
1591
    /// ```
1592
    #[cfg(feature = "alloc")]
1593
    #[must_use]
1594
    #[inline]
1595
0
    fn replacen<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1596
0
        &self,
1597
0
        needle: N,
1598
0
        replacement: R,
1599
0
        limit: usize,
1600
0
    ) -> Vec<u8> {
1601
0
        let mut dest = Vec::with_capacity(self.as_bytes().len());
1602
0
        self.replacen_into(needle, replacement, limit, &mut dest);
1603
0
        dest
1604
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen::<_, _>
1605
1606
    /// Replace all matches of the given needle with the given replacement,
1607
    /// and write the result into the provided `Vec<u8>`.
1608
    ///
1609
    /// This does **not** clear `dest` before writing to it.
1610
    ///
1611
    /// This routine is useful for reusing allocation. For a more convenient
1612
    /// API, use [`replace`](#method.replace) instead.
1613
    ///
1614
    /// # Examples
1615
    ///
1616
    /// Basic usage:
1617
    ///
1618
    /// ```
1619
    /// use bstr::ByteSlice;
1620
    ///
1621
    /// let s = b"this is old";
1622
    ///
1623
    /// let mut dest = vec![];
1624
    /// s.replace_into("old", "new", &mut dest);
1625
    /// assert_eq!(dest, "this is new".as_bytes());
1626
    /// ```
1627
    ///
1628
    /// When the pattern doesn't match:
1629
    ///
1630
    /// ```
1631
    /// use bstr::ByteSlice;
1632
    ///
1633
    /// let s = b"this is old";
1634
    ///
1635
    /// let mut dest = vec![];
1636
    /// s.replace_into("nada nada", "limonada", &mut dest);
1637
    /// assert_eq!(dest, "this is old".as_bytes());
1638
    /// ```
1639
    ///
1640
    /// When the needle is an empty string:
1641
    ///
1642
    /// ```
1643
    /// use bstr::ByteSlice;
1644
    ///
1645
    /// let s = b"foo";
1646
    ///
1647
    /// let mut dest = vec![];
1648
    /// s.replace_into("", "Z", &mut dest);
1649
    /// assert_eq!(dest, "ZfZoZoZ".as_bytes());
1650
    /// ```
1651
    #[cfg(feature = "alloc")]
1652
    #[inline]
1653
0
    fn replace_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1654
0
        &self,
1655
0
        needle: N,
1656
0
        replacement: R,
1657
0
        dest: &mut Vec<u8>,
1658
0
    ) {
1659
0
        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
1660
1661
0
        let mut last = 0;
1662
0
        for start in self.find_iter(needle) {
1663
0
            dest.push_str(&self.as_bytes()[last..start]);
1664
0
            dest.push_str(replacement);
1665
0
            last = start + needle.len();
1666
0
        }
1667
0
        dest.push_str(&self.as_bytes()[last..]);
1668
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace_into::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace_into::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replace_into::<_, _>
1669
1670
    /// Replace up to `limit` matches of the given needle with the given
1671
    /// replacement, and write the result into the provided `Vec<u8>`.
1672
    ///
1673
    /// This does **not** clear `dest` before writing to it.
1674
    ///
1675
    /// This routine is useful for reusing allocation. For a more convenient
1676
    /// API, use [`replacen`](#method.replacen) instead.
1677
    ///
1678
    /// # Examples
1679
    ///
1680
    /// Basic usage:
1681
    ///
1682
    /// ```
1683
    /// use bstr::ByteSlice;
1684
    ///
1685
    /// let s = b"foofoo";
1686
    ///
1687
    /// let mut dest = vec![];
1688
    /// s.replacen_into("o", "z", 2, &mut dest);
1689
    /// assert_eq!(dest, "fzzfoo".as_bytes());
1690
    /// ```
1691
    ///
1692
    /// When the pattern doesn't match:
1693
    ///
1694
    /// ```
1695
    /// use bstr::ByteSlice;
1696
    ///
1697
    /// let s = b"foofoo";
1698
    ///
1699
    /// let mut dest = vec![];
1700
    /// s.replacen_into("a", "z", 2, &mut dest);
1701
    /// assert_eq!(dest, "foofoo".as_bytes());
1702
    /// ```
1703
    ///
1704
    /// When the needle is an empty string:
1705
    ///
1706
    /// ```
1707
    /// use bstr::ByteSlice;
1708
    ///
1709
    /// let s = b"foo";
1710
    ///
1711
    /// let mut dest = vec![];
1712
    /// s.replacen_into("", "Z", 2, &mut dest);
1713
    /// assert_eq!(dest, "ZfZoo".as_bytes());
1714
    /// ```
1715
    #[cfg(feature = "alloc")]
1716
    #[inline]
1717
0
    fn replacen_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1718
0
        &self,
1719
0
        needle: N,
1720
0
        replacement: R,
1721
0
        limit: usize,
1722
0
        dest: &mut Vec<u8>,
1723
0
    ) {
1724
0
        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
1725
1726
0
        let mut last = 0;
1727
0
        for start in self.find_iter(needle).take(limit) {
1728
0
            dest.push_str(&self.as_bytes()[last..start]);
1729
0
            dest.push_str(replacement);
1730
0
            last = start + needle.len();
1731
0
        }
1732
0
        dest.push_str(&self.as_bytes()[last..]);
1733
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen_into::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen_into::<_, _>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::replacen_into::<_, _>
1734
1735
    /// Returns an iterator over the bytes in this byte string.
1736
    ///
1737
    /// # Examples
1738
    ///
1739
    /// Basic usage:
1740
    ///
1741
    /// ```
1742
    /// use bstr::ByteSlice;
1743
    ///
1744
    /// let bs = b"foobar";
1745
    /// let bytes: Vec<u8> = bs.bytes().collect();
1746
    /// assert_eq!(bytes, bs);
1747
    /// ```
1748
    #[inline]
1749
4.77M
    fn bytes(&self) -> Bytes<'_> {
1750
4.77M
        Bytes { it: self.as_bytes().iter() }
1751
4.77M
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::bytes
<[u8] as bstr::ext_slice::ByteSlice>::bytes
Line
Count
Source
1749
3.95k
    fn bytes(&self) -> Bytes<'_> {
1750
3.95k
        Bytes { it: self.as_bytes().iter() }
1751
3.95k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::bytes
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::bytes
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::bytes
<[u8] as bstr::ext_slice::ByteSlice>::bytes
Line
Count
Source
1749
29.7k
    fn bytes(&self) -> Bytes<'_> {
1750
29.7k
        Bytes { it: self.as_bytes().iter() }
1751
29.7k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::bytes
<[u8] as bstr::ext_slice::ByteSlice>::bytes
Line
Count
Source
1749
4.73M
    fn bytes(&self) -> Bytes<'_> {
1750
4.73M
        Bytes { it: self.as_bytes().iter() }
1751
4.73M
    }
1752
1753
    /// Returns an iterator over the Unicode scalar values in this byte string.
1754
    /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint
1755
    /// is yielded instead.
1756
    ///
1757
    /// # Examples
1758
    ///
1759
    /// Basic usage:
1760
    ///
1761
    /// ```
1762
    /// use bstr::ByteSlice;
1763
    ///
1764
    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
1765
    /// let chars: Vec<char> = bs.chars().collect();
1766
    /// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
1767
    /// ```
1768
    ///
1769
    /// Codepoints can also be iterated over in reverse:
1770
    ///
1771
    /// ```
1772
    /// use bstr::ByteSlice;
1773
    ///
1774
    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
1775
    /// let chars: Vec<char> = bs.chars().rev().collect();
1776
    /// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
1777
    /// ```
1778
    #[inline]
1779
0
    fn chars(&self) -> Chars<'_> {
1780
0
        Chars::new(self.as_bytes())
1781
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::chars
1782
1783
    /// Returns an iterator over the Unicode scalar values in this byte string
1784
    /// along with their starting and ending byte index positions. If invalid
1785
    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
1786
    /// instead.
1787
    ///
1788
    /// Note that this is slightly different from the `CharIndices` iterator
1789
    /// provided by the standard library. Aside from working on possibly
1790
    /// invalid UTF-8, this iterator provides both the corresponding starting
1791
    /// and ending byte indices of each codepoint yielded. The ending position
1792
    /// is necessary to slice the original byte string when invalid UTF-8 bytes
1793
    /// are converted into a Unicode replacement codepoint, since a single
1794
    /// replacement codepoint can substitute anywhere from 1 to 3 invalid bytes
1795
    /// (inclusive).
1796
    ///
1797
    /// # Examples
1798
    ///
1799
    /// Basic usage:
1800
    ///
1801
    /// ```
1802
    /// use bstr::ByteSlice;
1803
    ///
1804
    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
1805
    /// let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
1806
    /// assert_eq!(chars, vec![
1807
    ///     (0, 3, '☃'),
1808
    ///     (3, 4, '\u{FFFD}'),
1809
    ///     (4, 8, '𝞃'),
1810
    ///     (8, 10, '\u{FFFD}'),
1811
    ///     (10, 11, 'a'),
1812
    /// ]);
1813
    /// ```
1814
    ///
1815
    /// Codepoints can also be iterated over in reverse:
1816
    ///
1817
    /// ```
1818
    /// use bstr::ByteSlice;
1819
    ///
1820
    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
1821
    /// let chars: Vec<(usize, usize, char)> = bs
1822
    ///     .char_indices()
1823
    ///     .rev()
1824
    ///     .collect();
1825
    /// assert_eq!(chars, vec![
1826
    ///     (10, 11, 'a'),
1827
    ///     (8, 10, '\u{FFFD}'),
1828
    ///     (4, 8, '𝞃'),
1829
    ///     (3, 4, '\u{FFFD}'),
1830
    ///     (0, 3, '☃'),
1831
    /// ]);
1832
    /// ```
1833
    #[inline]
1834
31.3k
    fn char_indices(&self) -> CharIndices<'_> {
1835
31.3k
        CharIndices::new(self.as_bytes())
1836
31.3k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
<[u8] as bstr::ext_slice::ByteSlice>::char_indices
Line
Count
Source
1834
19.1k
    fn char_indices(&self) -> CharIndices<'_> {
1835
19.1k
        CharIndices::new(self.as_bytes())
1836
19.1k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
<[u8] as bstr::ext_slice::ByteSlice>::char_indices
Line
Count
Source
1834
242
    fn char_indices(&self) -> CharIndices<'_> {
1835
242
        CharIndices::new(self.as_bytes())
1836
242
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
<[u8] as bstr::ext_slice::ByteSlice>::char_indices
Line
Count
Source
1834
11.8k
    fn char_indices(&self) -> CharIndices<'_> {
1835
11.8k
        CharIndices::new(self.as_bytes())
1836
11.8k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::char_indices
1837
1838
    /// Iterate over chunks of valid UTF-8.
1839
    ///
1840
    /// The iterator returned yields chunks of valid UTF-8 separated by invalid
1841
    /// UTF-8 bytes, if they exist. Invalid UTF-8 bytes are always 1-3 bytes,
1842
    /// which are determined via the "substitution of maximal subparts"
1843
    /// strategy described in the docs for the
1844
    /// [`ByteSlice::to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy)
1845
    /// method.
1846
    ///
1847
    /// # Examples
1848
    ///
1849
    /// This example shows how to gather all valid and invalid chunks from a
1850
    /// byte slice:
1851
    ///
1852
    /// ```
1853
    /// use bstr::{ByteSlice, Utf8Chunk};
1854
    ///
1855
    /// let bytes = b"foo\xFD\xFEbar\xFF";
1856
    ///
1857
    /// let (mut valid_chunks, mut invalid_chunks) = (vec![], vec![]);
1858
    /// for chunk in bytes.utf8_chunks() {
1859
    ///     if !chunk.valid().is_empty() {
1860
    ///         valid_chunks.push(chunk.valid());
1861
    ///     }
1862
    ///     if !chunk.invalid().is_empty() {
1863
    ///         invalid_chunks.push(chunk.invalid());
1864
    ///     }
1865
    /// }
1866
    ///
1867
    /// assert_eq!(valid_chunks, vec!["foo", "bar"]);
1868
    /// assert_eq!(invalid_chunks, vec![b"\xFD", b"\xFE", b"\xFF"]);
1869
    /// ```
1870
    #[inline]
1871
0
    fn utf8_chunks(&self) -> Utf8Chunks<'_> {
1872
0
        Utf8Chunks { bytes: self.as_bytes() }
1873
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::utf8_chunks
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::utf8_chunks
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::utf8_chunks
1874
1875
    /// Returns an iterator over the grapheme clusters in this byte string.
1876
    /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint
1877
    /// is yielded instead.
1878
    ///
1879
    /// # Examples
1880
    ///
1881
    /// This example shows how multiple codepoints can combine to form a
1882
    /// single grapheme cluster:
1883
    ///
1884
    /// ```
1885
    /// use bstr::ByteSlice;
1886
    ///
1887
    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
1888
    /// let graphemes: Vec<&str> = bs.graphemes().collect();
1889
    /// assert_eq!(vec!["à̖", "🇺🇸"], graphemes);
1890
    /// ```
1891
    ///
1892
    /// This shows that graphemes can be iterated over in reverse:
1893
    ///
1894
    /// ```
1895
    /// use bstr::ByteSlice;
1896
    ///
1897
    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
1898
    /// let graphemes: Vec<&str> = bs.graphemes().rev().collect();
1899
    /// assert_eq!(vec!["🇺🇸", "à̖"], graphemes);
1900
    /// ```
1901
    #[cfg(feature = "unicode")]
1902
    #[inline]
1903
0
    fn graphemes(&self) -> Graphemes<'_> {
1904
0
        Graphemes::new(self.as_bytes())
1905
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::graphemes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::graphemes
1906
1907
    /// Returns an iterator over the grapheme clusters in this byte string
1908
    /// along with their starting and ending byte index positions. If invalid
1909
    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
1910
    /// instead.
1911
    ///
1912
    /// # Examples
1913
    ///
1914
    /// This example shows how to get the byte offsets of each individual
1915
    /// grapheme cluster:
1916
    ///
1917
    /// ```
1918
    /// use bstr::ByteSlice;
1919
    ///
1920
    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
1921
    /// let graphemes: Vec<(usize, usize, &str)> =
1922
    ///     bs.grapheme_indices().collect();
1923
    /// assert_eq!(vec![(0, 5, "à̖"), (5, 13, "🇺🇸")], graphemes);
1924
    /// ```
1925
    ///
1926
    /// This example shows what happens when invalid UTF-8 is encountered. Note
1927
    /// that the offsets are valid indices into the original string, and do
1928
    /// not necessarily correspond to the length of the `&str` returned!
1929
    ///
1930
    /// ```
1931
    /// # #[cfg(all(feature = "alloc"))] {
1932
    /// use bstr::{ByteSlice, ByteVec};
1933
    ///
1934
    /// let mut bytes = vec![];
1935
    /// bytes.push_str("a\u{0300}\u{0316}");
1936
    /// bytes.push(b'\xFF');
1937
    /// bytes.push_str("\u{1F1FA}\u{1F1F8}");
1938
    ///
1939
    /// let graphemes: Vec<(usize, usize, &str)> =
1940
    ///     bytes.grapheme_indices().collect();
1941
    /// assert_eq!(
1942
    ///     graphemes,
1943
    ///     vec![(0, 5, "à̖"), (5, 6, "\u{FFFD}"), (6, 14, "🇺🇸")]
1944
    /// );
1945
    /// # }
1946
    /// ```
1947
    #[cfg(feature = "unicode")]
1948
    #[inline]
1949
0
    fn grapheme_indices(&self) -> GraphemeIndices<'_> {
1950
0
        GraphemeIndices::new(self.as_bytes())
1951
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::grapheme_indices
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::grapheme_indices
1952
1953
    /// Returns an iterator over the words in this byte string. If invalid
1954
    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
1955
    /// instead.
1956
    ///
1957
    /// This is similar to
1958
    /// [`words_with_breaks`](trait.ByteSlice.html#method.words_with_breaks),
1959
    /// except it only returns elements that contain a "word" character. A word
1960
    /// character is defined by UTS #18 (Annex C) to be the combination of the
1961
    /// `Alphabetic` and `Join_Control` properties, along with the
1962
    /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general
1963
    /// categories.
1964
    ///
1965
    /// Since words are made up of one or more codepoints, this iterator
1966
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
1967
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
1968
    ///
1969
    /// # Examples
1970
    ///
1971
    /// Basic usage:
1972
    ///
1973
    /// ```
1974
    /// use bstr::ByteSlice;
1975
    ///
1976
    /// let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
1977
    /// let words: Vec<&str> = bs.words().collect();
1978
    /// assert_eq!(words, vec![
1979
    ///     "The", "quick", "brown", "fox", "can't",
1980
    ///     "jump", "32.3", "feet", "right",
1981
    /// ]);
1982
    /// ```
1983
    #[cfg(feature = "unicode")]
1984
    #[inline]
1985
0
    fn words(&self) -> Words<'_> {
1986
0
        Words::new(self.as_bytes())
1987
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words
1988
1989
    /// Returns an iterator over the words in this byte string along with
1990
    /// their starting and ending byte index positions.
1991
    ///
1992
    /// This is similar to
1993
    /// [`words_with_break_indices`](trait.ByteSlice.html#method.words_with_break_indices),
1994
    /// except it only returns elements that contain a "word" character. A word
1995
    /// character is defined by UTS #18 (Annex C) to be the combination of the
1996
    /// `Alphabetic` and `Join_Control` properties, along with the
1997
    /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general
1998
    /// categories.
1999
    ///
2000
    /// Since words are made up of one or more codepoints, this iterator
2001
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
2002
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
2003
    ///
2004
    /// # Examples
2005
    ///
2006
    /// This example shows how to get the byte offsets of each individual
2007
    /// word:
2008
    ///
2009
    /// ```
2010
    /// use bstr::ByteSlice;
2011
    ///
2012
    /// let bs = b"can't jump 32.3 feet";
2013
    /// let words: Vec<(usize, usize, &str)> = bs.word_indices().collect();
2014
    /// assert_eq!(words, vec![
2015
    ///     (0, 5, "can't"),
2016
    ///     (6, 10, "jump"),
2017
    ///     (11, 15, "32.3"),
2018
    ///     (16, 20, "feet"),
2019
    /// ]);
2020
    /// ```
2021
    #[cfg(feature = "unicode")]
2022
    #[inline]
2023
0
    fn word_indices(&self) -> WordIndices<'_> {
2024
0
        WordIndices::new(self.as_bytes())
2025
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::word_indices
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::word_indices
2026
2027
    /// Returns an iterator over the words in this byte string, along with
2028
    /// all breaks between the words. Concatenating all elements yielded by
2029
    /// the iterator results in the original string (modulo Unicode replacement
2030
    /// codepoint substitutions if invalid UTF-8 is encountered).
2031
    ///
2032
    /// Since words are made up of one or more codepoints, this iterator
2033
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
2034
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
2035
    ///
2036
    /// # Examples
2037
    ///
2038
    /// Basic usage:
2039
    ///
2040
    /// ```
2041
    /// use bstr::ByteSlice;
2042
    ///
2043
    /// let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
2044
    /// let words: Vec<&str> = bs.words_with_breaks().collect();
2045
    /// assert_eq!(words, vec![
2046
    ///     "The", " ", "quick", " ", "(", "\"", "brown", "\"", ")",
2047
    ///     " ", "fox", " ", "can't", " ", "jump", " ", "32.3", " ", "feet",
2048
    ///     ",", " ", "right", "?",
2049
    /// ]);
2050
    /// ```
2051
    #[cfg(feature = "unicode")]
2052
    #[inline]
2053
0
    fn words_with_breaks(&self) -> WordsWithBreaks<'_> {
2054
0
        WordsWithBreaks::new(self.as_bytes())
2055
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words_with_breaks
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words_with_breaks
2056
2057
    /// Returns an iterator over the words and their byte offsets in this
2058
    /// byte string, along with all breaks between the words. Concatenating
2059
    /// all elements yielded by the iterator results in the original string
2060
    /// (modulo Unicode replacement codepoint substitutions if invalid UTF-8 is
2061
    /// encountered).
2062
    ///
2063
    /// Since words are made up of one or more codepoints, this iterator
2064
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
2065
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
2066
    ///
2067
    /// # Examples
2068
    ///
2069
    /// This example shows how to get the byte offsets of each individual
2070
    /// word:
2071
    ///
2072
    /// ```
2073
    /// use bstr::ByteSlice;
2074
    ///
2075
    /// let bs = b"can't jump 32.3 feet";
2076
    /// let words: Vec<(usize, usize, &str)> =
2077
    ///     bs.words_with_break_indices().collect();
2078
    /// assert_eq!(words, vec![
2079
    ///     (0, 5, "can't"),
2080
    ///     (5, 6, " "),
2081
    ///     (6, 10, "jump"),
2082
    ///     (10, 11, " "),
2083
    ///     (11, 15, "32.3"),
2084
    ///     (15, 16, " "),
2085
    ///     (16, 20, "feet"),
2086
    /// ]);
2087
    /// ```
2088
    #[cfg(feature = "unicode")]
2089
    #[inline]
2090
0
    fn words_with_break_indices(&self) -> WordsWithBreakIndices<'_> {
2091
0
        WordsWithBreakIndices::new(self.as_bytes())
2092
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words_with_break_indices
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::words_with_break_indices
2093
2094
    /// Returns an iterator over the sentences in this byte string.
2095
    ///
2096
    /// Typically, a sentence will include its trailing punctuation and
2097
    /// whitespace. Concatenating all elements yielded by the iterator
2098
    /// results in the original string (modulo Unicode replacement codepoint
2099
    /// substitutions if invalid UTF-8 is encountered).
2100
    ///
2101
    /// Since sentences are made up of one or more codepoints, this iterator
2102
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
2103
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
2104
    ///
2105
    /// # Examples
2106
    ///
2107
    /// Basic usage:
2108
    ///
2109
    /// ```
2110
    /// use bstr::ByteSlice;
2111
    ///
2112
    /// let bs = b"I want this. Not that. Right now.";
2113
    /// let sentences: Vec<&str> = bs.sentences().collect();
2114
    /// assert_eq!(sentences, vec![
2115
    ///     "I want this. ",
2116
    ///     "Not that. ",
2117
    ///     "Right now.",
2118
    /// ]);
2119
    /// ```
2120
    #[cfg(feature = "unicode")]
2121
    #[inline]
2122
0
    fn sentences(&self) -> Sentences<'_> {
2123
0
        Sentences::new(self.as_bytes())
2124
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::sentences
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::sentences
2125
2126
    /// Returns an iterator over the sentences in this byte string along with
2127
    /// their starting and ending byte index positions.
2128
    ///
2129
    /// Typically, a sentence will include its trailing punctuation and
2130
    /// whitespace. Concatenating all elements yielded by the iterator
2131
    /// results in the original string (modulo Unicode replacement codepoint
2132
    /// substitutions if invalid UTF-8 is encountered).
2133
    ///
2134
    /// Since sentences are made up of one or more codepoints, this iterator
2135
    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
2136
    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
2137
    ///
2138
    /// # Examples
2139
    ///
2140
    /// Basic usage:
2141
    ///
2142
    /// ```
2143
    /// use bstr::ByteSlice;
2144
    ///
2145
    /// let bs = b"I want this. Not that. Right now.";
2146
    /// let sentences: Vec<(usize, usize, &str)> =
2147
    ///     bs.sentence_indices().collect();
2148
    /// assert_eq!(sentences, vec![
2149
    ///     (0, 13, "I want this. "),
2150
    ///     (13, 23, "Not that. "),
2151
    ///     (23, 33, "Right now."),
2152
    /// ]);
2153
    /// ```
2154
    #[cfg(feature = "unicode")]
2155
    #[inline]
2156
0
    fn sentence_indices(&self) -> SentenceIndices<'_> {
2157
0
        SentenceIndices::new(self.as_bytes())
2158
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::sentence_indices
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::sentence_indices
2159
2160
    /// An iterator over all lines in a byte string, without their
2161
    /// terminators.
2162
    ///
2163
    /// For this iterator, the only line terminators recognized are `\r\n` and
2164
    /// `\n`.
2165
    ///
2166
    /// # Examples
2167
    ///
2168
    /// Basic usage:
2169
    ///
2170
    /// ```
2171
    /// use bstr::{B, ByteSlice};
2172
    ///
2173
    /// let s = b"\
2174
    /// foo
2175
    ///
2176
    /// bar\r
2177
    /// baz
2178
    ///
2179
    ///
2180
    /// quux";
2181
    /// let lines: Vec<&[u8]> = s.lines().collect();
2182
    /// assert_eq!(lines, vec![
2183
    ///     B("foo"), B(""), B("bar"), B("baz"), B(""), B(""), B("quux"),
2184
    /// ]);
2185
    /// ```
2186
    #[inline]
2187
34.5k
    fn lines(&self) -> Lines<'_> {
2188
34.5k
        Lines::new(self.as_bytes())
2189
34.5k
    }
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
4.04k
    fn lines(&self) -> Lines<'_> {
2188
4.04k
        Lines::new(self.as_bytes())
2189
4.04k
    }
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
4.04k
    fn lines(&self) -> Lines<'_> {
2188
4.04k
        Lines::new(self.as_bytes())
2189
4.04k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
131
    fn lines(&self) -> Lines<'_> {
2188
131
        Lines::new(self.as_bytes())
2189
131
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
2.71k
    fn lines(&self) -> Lines<'_> {
2188
2.71k
        Lines::new(self.as_bytes())
2189
2.71k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
2.03k
    fn lines(&self) -> Lines<'_> {
2188
2.03k
        Lines::new(self.as_bytes())
2189
2.03k
    }
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
14.7k
    fn lines(&self) -> Lines<'_> {
2188
14.7k
        Lines::new(self.as_bytes())
2189
14.7k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
<[u8] as bstr::ext_slice::ByteSlice>::lines
Line
Count
Source
2187
6.92k
    fn lines(&self) -> Lines<'_> {
2188
6.92k
        Lines::new(self.as_bytes())
2189
6.92k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines
2190
2191
    /// An iterator over all lines in a byte string, including their
2192
    /// terminators.
2193
    ///
2194
    /// For this iterator, the only line terminator recognized is `\n`. (Since
2195
    /// line terminators are included, this also handles `\r\n` line endings.)
2196
    ///
2197
    /// Line terminators are only included if they are present in the original
2198
    /// byte string. For example, the last line in a byte string may not end
2199
    /// with a line terminator.
2200
    ///
2201
    /// Concatenating all elements yielded by this iterator is guaranteed to
2202
    /// yield the original byte string.
2203
    ///
2204
    /// # Examples
2205
    ///
2206
    /// Basic usage:
2207
    ///
2208
    /// ```
2209
    /// use bstr::{B, ByteSlice};
2210
    ///
2211
    /// let s = b"\
2212
    /// foo
2213
    ///
2214
    /// bar\r
2215
    /// baz
2216
    ///
2217
    ///
2218
    /// quux";
2219
    /// let lines: Vec<&[u8]> = s.lines_with_terminator().collect();
2220
    /// assert_eq!(lines, vec![
2221
    ///     B("foo\n"),
2222
    ///     B("\n"),
2223
    ///     B("bar\r\n"),
2224
    ///     B("baz\n"),
2225
    ///     B("\n"),
2226
    ///     B("\n"),
2227
    ///     B("quux"),
2228
    /// ]);
2229
    /// ```
2230
    #[inline]
2231
70.5k
    fn lines_with_terminator(&self) -> LinesWithTerminator<'_> {
2232
70.5k
        LinesWithTerminator::new(self.as_bytes())
2233
70.5k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::lines_with_terminator
<[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
Line
Count
Source
2231
70.5k
    fn lines_with_terminator(&self) -> LinesWithTerminator<'_> {
2232
70.5k
        LinesWithTerminator::new(self.as_bytes())
2233
70.5k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::lines_with_terminator
2234
2235
    /// Return a byte string slice with leading and trailing whitespace
2236
    /// removed.
2237
    ///
2238
    /// Whitespace is defined according to the terms of the `White_Space`
2239
    /// Unicode property.
2240
    ///
2241
    /// # Examples
2242
    ///
2243
    /// Basic usage:
2244
    ///
2245
    /// ```
2246
    /// use bstr::{B, ByteSlice};
2247
    ///
2248
    /// let s = B(" foo\tbar\t\u{2003}\n");
2249
    /// assert_eq!(s.trim(), B("foo\tbar"));
2250
    /// ```
2251
    #[cfg(feature = "unicode")]
2252
    #[inline]
2253
2.99M
    fn trim(&self) -> &[u8] {
2254
2.99M
        self.trim_start().trim_end()
2255
2.99M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim
Line
Count
Source
2253
2.98M
    fn trim(&self) -> &[u8] {
2254
2.98M
        self.trim_start().trim_end()
2255
2.98M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim
Line
Count
Source
2253
8.67k
    fn trim(&self) -> &[u8] {
2254
8.67k
        self.trim_start().trim_end()
2255
8.67k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
<[u8] as bstr::ext_slice::ByteSlice>::trim
Line
Count
Source
2253
2.71k
    fn trim(&self) -> &[u8] {
2254
2.71k
        self.trim_start().trim_end()
2255
2.71k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim
2256
2257
    /// Return a byte string slice with leading whitespace removed.
2258
    ///
2259
    /// Whitespace is defined according to the terms of the `White_Space`
2260
    /// Unicode property.
2261
    ///
2262
    /// # Examples
2263
    ///
2264
    /// Basic usage:
2265
    ///
2266
    /// ```
2267
    /// use bstr::{B, ByteSlice};
2268
    ///
2269
    /// let s = B(" foo\tbar\t\u{2003}\n");
2270
    /// assert_eq!(s.trim_start(), B("foo\tbar\t\u{2003}\n"));
2271
    /// ```
2272
    #[cfg(feature = "unicode")]
2273
    #[inline]
2274
2.99M
    fn trim_start(&self) -> &[u8] {
2275
2.99M
        let start = whitespace_len_fwd(self.as_bytes());
2276
2.99M
        &self.as_bytes()[start..]
2277
2.99M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim_start
Line
Count
Source
2274
2.98M
    fn trim_start(&self) -> &[u8] {
2275
2.98M
        let start = whitespace_len_fwd(self.as_bytes());
2276
2.98M
        &self.as_bytes()[start..]
2277
2.98M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim_start
Line
Count
Source
2274
8.67k
    fn trim_start(&self) -> &[u8] {
2275
8.67k
        let start = whitespace_len_fwd(self.as_bytes());
2276
8.67k
        &self.as_bytes()[start..]
2277
8.67k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
<[u8] as bstr::ext_slice::ByteSlice>::trim_start
Line
Count
Source
2274
2.71k
    fn trim_start(&self) -> &[u8] {
2275
2.71k
        let start = whitespace_len_fwd(self.as_bytes());
2276
2.71k
        &self.as_bytes()[start..]
2277
2.71k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_start
2278
2279
    /// Return a byte string slice with trailing whitespace removed.
2280
    ///
2281
    /// Whitespace is defined according to the terms of the `White_Space`
2282
    /// Unicode property.
2283
    ///
2284
    /// # Examples
2285
    ///
2286
    /// Basic usage:
2287
    ///
2288
    /// ```
2289
    /// use bstr::{B, ByteSlice};
2290
    ///
2291
    /// let s = B(" foo\tbar\t\u{2003}\n");
2292
    /// assert_eq!(s.trim_end(), B(" foo\tbar"));
2293
    /// ```
2294
    #[cfg(feature = "unicode")]
2295
    #[inline]
2296
2.99M
    fn trim_end(&self) -> &[u8] {
2297
2.99M
        let end = whitespace_len_rev(self.as_bytes());
2298
2.99M
        &self.as_bytes()[..end]
2299
2.99M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim_end
Line
Count
Source
2296
2.98M
    fn trim_end(&self) -> &[u8] {
2297
2.98M
        let end = whitespace_len_rev(self.as_bytes());
2298
2.98M
        &self.as_bytes()[..end]
2299
2.98M
    }
<[u8] as bstr::ext_slice::ByteSlice>::trim_end
Line
Count
Source
2296
8.67k
    fn trim_end(&self) -> &[u8] {
2297
8.67k
        let end = whitespace_len_rev(self.as_bytes());
2298
8.67k
        &self.as_bytes()[..end]
2299
8.67k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
<[u8] as bstr::ext_slice::ByteSlice>::trim_end
Line
Count
Source
2296
2.71k
    fn trim_end(&self) -> &[u8] {
2297
2.71k
        let end = whitespace_len_rev(self.as_bytes());
2298
2.71k
        &self.as_bytes()[..end]
2299
2.71k
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::trim_end
2300
2301
    /// Return a byte string slice with leading and trailing characters
2302
    /// satisfying the given predicate removed.
2303
    ///
2304
    /// # Examples
2305
    ///
2306
    /// Basic usage:
2307
    ///
2308
    /// ```
2309
    /// use bstr::{B, ByteSlice};
2310
    ///
2311
    /// let s = b"123foo5bar789";
2312
    /// assert_eq!(s.trim_with(|c| c.is_numeric()), B("foo5bar"));
2313
    /// ```
2314
    #[inline]
2315
5.93k
    fn trim_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2316
5.93k
        self.trim_start_with(&mut trim).trim_end_with(&mut trim)
2317
5.93k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_with::<_>
<[u8] as bstr::ext_slice::ByteSlice>::trim_with::<<gix_credentials::protocol::Context>::destructure_url_in_place::{closure#1}>
Line
Count
Source
2315
5.93k
    fn trim_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2316
5.93k
        self.trim_start_with(&mut trim).trim_end_with(&mut trim)
2317
5.93k
    }
2318
2319
    /// Return a byte string slice with leading characters satisfying the given
2320
    /// predicate removed.
2321
    ///
2322
    /// # Examples
2323
    ///
2324
    /// Basic usage:
2325
    ///
2326
    /// ```
2327
    /// use bstr::{B, ByteSlice};
2328
    ///
2329
    /// let s = b"123foo5bar789";
2330
    /// assert_eq!(s.trim_start_with(|c| c.is_numeric()), B("foo5bar789"));
2331
    /// ```
2332
    #[inline]
2333
5.93k
    fn trim_start_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2334
2.14M
        for (s, _, ch) in self.char_indices() {
2335
2.14M
            if !trim(ch) {
2336
3.95k
                return &self.as_bytes()[s..];
2337
2.14M
            }
2338
        }
2339
1.98k
        b""
2340
5.93k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_start_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_start_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_start_with::<_>
<[u8] as bstr::ext_slice::ByteSlice>::trim_start_with::<&mut <gix_credentials::protocol::Context>::destructure_url_in_place::{closure#1}>
Line
Count
Source
2333
5.93k
    fn trim_start_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2334
2.14M
        for (s, _, ch) in self.char_indices() {
2335
2.14M
            if !trim(ch) {
2336
3.95k
                return &self.as_bytes()[s..];
2337
2.14M
            }
2338
        }
2339
1.98k
        b""
2340
5.93k
    }
2341
2342
    /// Return a byte string slice with trailing characters satisfying the
2343
    /// given predicate removed.
2344
    ///
2345
    /// # Examples
2346
    ///
2347
    /// Basic usage:
2348
    ///
2349
    /// ```
2350
    /// use bstr::{B, ByteSlice};
2351
    ///
2352
    /// let s = b"123foo5bar789";
2353
    /// assert_eq!(s.trim_end_with(|c| c.is_numeric()), B("123foo5bar"));
2354
    /// ```
2355
    #[inline]
2356
5.93k
    fn trim_end_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2357
13.5k
        for (_, e, ch) in self.char_indices().rev() {
2358
13.5k
            if !trim(ch) {
2359
3.95k
                return &self.as_bytes()[..e];
2360
9.58k
            }
2361
        }
2362
1.98k
        b""
2363
5.93k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_end_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_end_with::<_>
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::trim_end_with::<_>
<[u8] as bstr::ext_slice::ByteSlice>::trim_end_with::<&mut <gix_credentials::protocol::Context>::destructure_url_in_place::{closure#1}>
Line
Count
Source
2356
5.93k
    fn trim_end_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2357
13.5k
        for (_, e, ch) in self.char_indices().rev() {
2358
13.5k
            if !trim(ch) {
2359
3.95k
                return &self.as_bytes()[..e];
2360
9.58k
            }
2361
        }
2362
1.98k
        b""
2363
5.93k
    }
2364
2365
    /// Returns a new `Vec<u8>` containing the lowercase equivalent of this
2366
    /// byte string.
2367
    ///
2368
    /// In this case, lowercase is defined according to the `Lowercase` Unicode
2369
    /// property.
2370
    ///
2371
    /// If invalid UTF-8 is seen, or if a character has no lowercase variant,
2372
    /// then it is written to the given buffer unchanged.
2373
    ///
2374
    /// Note that some characters in this byte string may expand into multiple
2375
    /// characters when changing the case, so the number of bytes written to
2376
    /// the given byte string may not be equivalent to the number of bytes in
2377
    /// this byte string.
2378
    ///
2379
    /// If you'd like to reuse an allocation for performance reasons, then use
2380
    /// [`to_lowercase_into`](#method.to_lowercase_into) instead.
2381
    ///
2382
    /// # Examples
2383
    ///
2384
    /// Basic usage:
2385
    ///
2386
    /// ```
2387
    /// use bstr::{B, ByteSlice};
2388
    ///
2389
    /// let s = B("HELLO Β");
2390
    /// assert_eq!("hello β".as_bytes(), s.to_lowercase().as_bytes());
2391
    /// ```
2392
    ///
2393
    /// Scripts without case are not changed:
2394
    ///
2395
    /// ```
2396
    /// use bstr::{B, ByteSlice};
2397
    ///
2398
    /// let s = B("农历新年");
2399
    /// assert_eq!("农历新年".as_bytes(), s.to_lowercase().as_bytes());
2400
    /// ```
2401
    ///
2402
    /// Invalid UTF-8 remains as is:
2403
    ///
2404
    /// ```
2405
    /// use bstr::{B, ByteSlice};
2406
    ///
2407
    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
2408
    /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s.to_lowercase().as_bytes());
2409
    /// ```
2410
    #[cfg(all(feature = "alloc", feature = "unicode"))]
2411
    #[inline]
2412
0
    fn to_lowercase(&self) -> Vec<u8> {
2413
0
        let mut buf = vec![];
2414
0
        self.to_lowercase_into(&mut buf);
2415
0
        buf
2416
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_lowercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_lowercase
2417
2418
    /// Writes the lowercase equivalent of this byte string into the given
2419
    /// buffer. The buffer is not cleared before written to.
2420
    ///
2421
    /// In this case, lowercase is defined according to the `Lowercase`
2422
    /// Unicode property.
2423
    ///
2424
    /// If invalid UTF-8 is seen, or if a character has no lowercase variant,
2425
    /// then it is written to the given buffer unchanged.
2426
    ///
2427
    /// Note that some characters in this byte string may expand into multiple
2428
    /// characters when changing the case, so the number of bytes written to
2429
    /// the given byte string may not be equivalent to the number of bytes in
2430
    /// this byte string.
2431
    ///
2432
    /// If you don't need to amortize allocation and instead prefer
2433
    /// convenience, then use [`to_lowercase`](#method.to_lowercase) instead.
2434
    ///
2435
    /// # Examples
2436
    ///
2437
    /// Basic usage:
2438
    ///
2439
    /// ```
2440
    /// use bstr::{B, ByteSlice};
2441
    ///
2442
    /// let s = B("HELLO Β");
2443
    ///
2444
    /// let mut buf = vec![];
2445
    /// s.to_lowercase_into(&mut buf);
2446
    /// assert_eq!("hello β".as_bytes(), buf.as_bytes());
2447
    /// ```
2448
    ///
2449
    /// Scripts without case are not changed:
2450
    ///
2451
    /// ```
2452
    /// use bstr::{B, ByteSlice};
2453
    ///
2454
    /// let s = B("农历新年");
2455
    ///
2456
    /// let mut buf = vec![];
2457
    /// s.to_lowercase_into(&mut buf);
2458
    /// assert_eq!("农历新年".as_bytes(), buf.as_bytes());
2459
    /// ```
2460
    ///
2461
    /// Invalid UTF-8 remains as is:
2462
    ///
2463
    /// ```
2464
    /// use bstr::{B, ByteSlice};
2465
    ///
2466
    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
2467
    ///
2468
    /// let mut buf = vec![];
2469
    /// s.to_lowercase_into(&mut buf);
2470
    /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), buf.as_bytes());
2471
    /// ```
2472
    #[cfg(all(feature = "alloc", feature = "unicode"))]
2473
    #[inline]
2474
0
    fn to_lowercase_into(&self, buf: &mut Vec<u8>) {
2475
        // TODO: This is the best we can do given what std exposes I think.
2476
        // If we roll our own case handling, then we might be able to do this
2477
        // a bit faster. We shouldn't roll our own case handling unless we
2478
        // need to, e.g., for doing caseless matching or case folding.
2479
2480
        // TODO(BUG): This doesn't handle any special casing rules.
2481
2482
0
        buf.reserve(self.as_bytes().len());
2483
0
        for (s, e, ch) in self.char_indices() {
2484
0
            if ch == '\u{FFFD}' {
2485
0
                buf.push_str(&self.as_bytes()[s..e]);
2486
0
            } else if ch.is_ascii() {
2487
0
                buf.push_char(ch.to_ascii_lowercase());
2488
0
            } else {
2489
0
                for upper in ch.to_lowercase() {
2490
0
                    buf.push_char(upper);
2491
0
                }
2492
            }
2493
        }
2494
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_lowercase_into
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_lowercase_into
2495
2496
    /// Returns a new `Vec<u8>` containing the ASCII lowercase equivalent of
2497
    /// this byte string.
2498
    ///
2499
    /// In this case, lowercase is only defined in ASCII letters. Namely, the
2500
    /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged.
2501
    /// In particular, the length of the byte string returned is always
2502
    /// equivalent to the length of this byte string.
2503
    ///
2504
    /// If you'd like to reuse an allocation for performance reasons, then use
2505
    /// [`make_ascii_lowercase`](#method.make_ascii_lowercase) to perform
2506
    /// the conversion in place.
2507
    ///
2508
    /// # Examples
2509
    ///
2510
    /// Basic usage:
2511
    ///
2512
    /// ```
2513
    /// use bstr::{B, ByteSlice};
2514
    ///
2515
    /// let s = B("HELLO Β");
2516
    /// assert_eq!("hello Β".as_bytes(), s.to_ascii_lowercase().as_bytes());
2517
    /// ```
2518
    ///
2519
    /// Invalid UTF-8 remains as is:
2520
    ///
2521
    /// ```
2522
    /// use bstr::{B, ByteSlice};
2523
    ///
2524
    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
2525
    /// assert_eq!(s.to_ascii_lowercase(), B(b"foo\xFFbar\xE2\x98baz"));
2526
    /// ```
2527
    #[cfg(feature = "alloc")]
2528
    #[inline]
2529
0
    fn to_ascii_lowercase(&self) -> Vec<u8> {
2530
0
        self.as_bytes().to_ascii_lowercase()
2531
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_lowercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_lowercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_lowercase
2532
2533
    /// Convert this byte string to its lowercase ASCII equivalent in place.
2534
    ///
2535
    /// In this case, lowercase is only defined in ASCII letters. Namely, the
2536
    /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged.
2537
    ///
2538
    /// If you don't need to do the conversion in
2539
    /// place and instead prefer convenience, then use
2540
    /// [`to_ascii_lowercase`](#method.to_ascii_lowercase) instead.
2541
    ///
2542
    /// # Examples
2543
    ///
2544
    /// Basic usage:
2545
    ///
2546
    /// ```
2547
    /// use bstr::ByteSlice;
2548
    ///
2549
    /// let mut s = <Vec<u8>>::from("HELLO Β");
2550
    /// s.make_ascii_lowercase();
2551
    /// assert_eq!(s, "hello Β".as_bytes());
2552
    /// ```
2553
    ///
2554
    /// Invalid UTF-8 remains as is:
2555
    ///
2556
    /// ```
2557
    /// # #[cfg(feature = "alloc")] {
2558
    /// use bstr::{B, ByteSlice, ByteVec};
2559
    ///
2560
    /// let mut s = <Vec<u8>>::from_slice(b"FOO\xFFBAR\xE2\x98BAZ");
2561
    /// s.make_ascii_lowercase();
2562
    /// assert_eq!(s, B(b"foo\xFFbar\xE2\x98baz"));
2563
    /// # }
2564
    /// ```
2565
    #[inline]
2566
0
    fn make_ascii_lowercase(&mut self) {
2567
0
        self.as_bytes_mut().make_ascii_lowercase();
2568
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_lowercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_lowercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_lowercase
2569
2570
    /// Returns a new `Vec<u8>` containing the uppercase equivalent of this
2571
    /// byte string.
2572
    ///
2573
    /// In this case, uppercase is defined according to the `Uppercase`
2574
    /// Unicode property.
2575
    ///
2576
    /// If invalid UTF-8 is seen, or if a character has no uppercase variant,
2577
    /// then it is written to the given buffer unchanged.
2578
    ///
2579
    /// Note that some characters in this byte string may expand into multiple
2580
    /// characters when changing the case, so the number of bytes written to
2581
    /// the given byte string may not be equivalent to the number of bytes in
2582
    /// this byte string.
2583
    ///
2584
    /// If you'd like to reuse an allocation for performance reasons, then use
2585
    /// [`to_uppercase_into`](#method.to_uppercase_into) instead.
2586
    ///
2587
    /// # Examples
2588
    ///
2589
    /// Basic usage:
2590
    ///
2591
    /// ```
2592
    /// use bstr::{B, ByteSlice};
2593
    ///
2594
    /// let s = B("hello β");
2595
    /// assert_eq!(s.to_uppercase(), B("HELLO Β"));
2596
    /// ```
2597
    ///
2598
    /// Scripts without case are not changed:
2599
    ///
2600
    /// ```
2601
    /// use bstr::{B, ByteSlice};
2602
    ///
2603
    /// let s = B("农历新年");
2604
    /// assert_eq!(s.to_uppercase(), B("农历新年"));
2605
    /// ```
2606
    ///
2607
    /// Invalid UTF-8 remains as is:
2608
    ///
2609
    /// ```
2610
    /// use bstr::{B, ByteSlice};
2611
    ///
2612
    /// let s = B(b"foo\xFFbar\xE2\x98baz");
2613
    /// assert_eq!(s.to_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
2614
    /// ```
2615
    #[cfg(all(feature = "alloc", feature = "unicode"))]
2616
    #[inline]
2617
0
    fn to_uppercase(&self) -> Vec<u8> {
2618
0
        let mut buf = vec![];
2619
0
        self.to_uppercase_into(&mut buf);
2620
0
        buf
2621
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_uppercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_uppercase
2622
2623
    /// Writes the uppercase equivalent of this byte string into the given
2624
    /// buffer. The buffer is not cleared before written to.
2625
    ///
2626
    /// In this case, uppercase is defined according to the `Uppercase`
2627
    /// Unicode property.
2628
    ///
2629
    /// If invalid UTF-8 is seen, or if a character has no uppercase variant,
2630
    /// then it is written to the given buffer unchanged.
2631
    ///
2632
    /// Note that some characters in this byte string may expand into multiple
2633
    /// characters when changing the case, so the number of bytes written to
2634
    /// the given byte string may not be equivalent to the number of bytes in
2635
    /// this byte string.
2636
    ///
2637
    /// If you don't need to amortize allocation and instead prefer
2638
    /// convenience, then use [`to_uppercase`](#method.to_uppercase) instead.
2639
    ///
2640
    /// # Examples
2641
    ///
2642
    /// Basic usage:
2643
    ///
2644
    /// ```
2645
    /// use bstr::{B, ByteSlice};
2646
    ///
2647
    /// let s = B("hello β");
2648
    ///
2649
    /// let mut buf = vec![];
2650
    /// s.to_uppercase_into(&mut buf);
2651
    /// assert_eq!(buf, B("HELLO Β"));
2652
    /// ```
2653
    ///
2654
    /// Scripts without case are not changed:
2655
    ///
2656
    /// ```
2657
    /// use bstr::{B, ByteSlice};
2658
    ///
2659
    /// let s = B("农历新年");
2660
    ///
2661
    /// let mut buf = vec![];
2662
    /// s.to_uppercase_into(&mut buf);
2663
    /// assert_eq!(buf, B("农历新年"));
2664
    /// ```
2665
    ///
2666
    /// Invalid UTF-8 remains as is:
2667
    ///
2668
    /// ```
2669
    /// use bstr::{B, ByteSlice};
2670
    ///
2671
    /// let s = B(b"foo\xFFbar\xE2\x98baz");
2672
    ///
2673
    /// let mut buf = vec![];
2674
    /// s.to_uppercase_into(&mut buf);
2675
    /// assert_eq!(buf, B(b"FOO\xFFBAR\xE2\x98BAZ"));
2676
    /// ```
2677
    #[cfg(all(feature = "alloc", feature = "unicode"))]
2678
    #[inline]
2679
0
    fn to_uppercase_into(&self, buf: &mut Vec<u8>) {
2680
        // TODO: This is the best we can do given what std exposes I think.
2681
        // If we roll our own case handling, then we might be able to do this
2682
        // a bit faster. We shouldn't roll our own case handling unless we
2683
        // need to, e.g., for doing caseless matching or case folding.
2684
0
        buf.reserve(self.as_bytes().len());
2685
0
        for (s, e, ch) in self.char_indices() {
2686
0
            if ch == '\u{FFFD}' {
2687
0
                buf.push_str(&self.as_bytes()[s..e]);
2688
0
            } else if ch.is_ascii() {
2689
0
                buf.push_char(ch.to_ascii_uppercase());
2690
0
            } else {
2691
0
                for upper in ch.to_uppercase() {
2692
0
                    buf.push_char(upper);
2693
0
                }
2694
            }
2695
        }
2696
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_uppercase_into
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_uppercase_into
2697
2698
    /// Returns a new `Vec<u8>` containing the ASCII uppercase equivalent of
2699
    /// this byte string.
2700
    ///
2701
    /// In this case, uppercase is only defined in ASCII letters. Namely, the
2702
    /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged.
2703
    /// In particular, the length of the byte string returned is always
2704
    /// equivalent to the length of this byte string.
2705
    ///
2706
    /// If you'd like to reuse an allocation for performance reasons, then use
2707
    /// [`make_ascii_uppercase`](#method.make_ascii_uppercase) to perform
2708
    /// the conversion in place.
2709
    ///
2710
    /// # Examples
2711
    ///
2712
    /// Basic usage:
2713
    ///
2714
    /// ```
2715
    /// use bstr::{B, ByteSlice};
2716
    ///
2717
    /// let s = B("hello β");
2718
    /// assert_eq!(s.to_ascii_uppercase(), B("HELLO β"));
2719
    /// ```
2720
    ///
2721
    /// Invalid UTF-8 remains as is:
2722
    ///
2723
    /// ```
2724
    /// use bstr::{B, ByteSlice};
2725
    ///
2726
    /// let s = B(b"foo\xFFbar\xE2\x98baz");
2727
    /// assert_eq!(s.to_ascii_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
2728
    /// ```
2729
    #[cfg(feature = "alloc")]
2730
    #[inline]
2731
0
    fn to_ascii_uppercase(&self) -> Vec<u8> {
2732
0
        self.as_bytes().to_ascii_uppercase()
2733
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_uppercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_uppercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::to_ascii_uppercase
2734
2735
    /// Convert this byte string to its uppercase ASCII equivalent in place.
2736
    ///
2737
    /// In this case, uppercase is only defined in ASCII letters. Namely, the
2738
    /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged.
2739
    ///
2740
    /// If you don't need to do the conversion in
2741
    /// place and instead prefer convenience, then use
2742
    /// [`to_ascii_uppercase`](#method.to_ascii_uppercase) instead.
2743
    ///
2744
    /// # Examples
2745
    ///
2746
    /// Basic usage:
2747
    ///
2748
    /// ```
2749
    /// use bstr::{B, ByteSlice};
2750
    ///
2751
    /// let mut s = <Vec<u8>>::from("hello β");
2752
    /// s.make_ascii_uppercase();
2753
    /// assert_eq!(s, B("HELLO β"));
2754
    /// ```
2755
    ///
2756
    /// Invalid UTF-8 remains as is:
2757
    ///
2758
    /// ```
2759
    /// # #[cfg(feature = "alloc")] {
2760
    /// use bstr::{B, ByteSlice, ByteVec};
2761
    ///
2762
    /// let mut s = <Vec<u8>>::from_slice(b"foo\xFFbar\xE2\x98baz");
2763
    /// s.make_ascii_uppercase();
2764
    /// assert_eq!(s, B(b"FOO\xFFBAR\xE2\x98BAZ"));
2765
    /// # }
2766
    /// ```
2767
    #[inline]
2768
0
    fn make_ascii_uppercase(&mut self) {
2769
0
        self.as_bytes_mut().make_ascii_uppercase();
2770
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_uppercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_uppercase
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::make_ascii_uppercase
2771
2772
    /// Escapes this byte string into a sequence of `char` values.
2773
    ///
2774
    /// When the sequence of `char` values is concatenated into a string, the
2775
    /// result is always valid UTF-8. Any unprintable or invalid UTF-8 in this
2776
    /// byte string are escaped using using `\xNN` notation. Moreover, the
2777
    /// characters `\0`, `\r`, `\n`, `\t` and `\` are escaped as well.
2778
    ///
2779
    /// This is useful when one wants to get a human readable view of the raw
2780
    /// bytes that is also valid UTF-8.
2781
    ///
2782
    /// The iterator returned implements the `Display` trait. So one can do
2783
    /// `b"foo\xFFbar".escape_bytes().to_string()` to get a `String` with its
2784
    /// bytes escaped.
2785
    ///
2786
    /// The dual of this function is [`ByteVec::unescape_bytes`].
2787
    ///
2788
    /// Note that this is similar to, but not equivalent to the `Debug`
2789
    /// implementation on [`BStr`] and [`BString`](crate::BString). The `Debug`
2790
    /// implementations also use the debug representation for all Unicode
2791
    /// codepoints. However, this escaping routine only escapes individual
2792
    /// bytes. All Unicode codepoints above `U+007F` are passed through
2793
    /// unchanged without any escaping.
2794
    ///
2795
    /// # Examples
2796
    ///
2797
    /// ```
2798
    /// # #[cfg(feature = "alloc")] {
2799
    /// use bstr::{B, ByteSlice};
2800
    ///
2801
    /// assert_eq!(r"foo\xFFbar", b"foo\xFFbar".escape_bytes().to_string());
2802
    /// assert_eq!(r"foo\nbar", b"foo\nbar".escape_bytes().to_string());
2803
    /// assert_eq!(r"foo\tbar", b"foo\tbar".escape_bytes().to_string());
2804
    /// assert_eq!(r"foo\\bar", b"foo\\bar".escape_bytes().to_string());
2805
    /// assert_eq!(r"foo☃bar", B("foo☃bar").escape_bytes().to_string());
2806
    /// # }
2807
    /// ```
2808
    #[inline]
2809
0
    fn escape_bytes(&self) -> EscapeBytes<'_> {
2810
0
        EscapeBytes::new(self.as_bytes())
2811
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::escape_bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::escape_bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::escape_bytes
2812
2813
    /// Reverse the bytes in this string, in place.
2814
    ///
2815
    /// This is not necessarily a well formed operation! For example, if this
2816
    /// byte string contains valid UTF-8 that isn't ASCII, then reversing the
2817
    /// string will likely result in invalid UTF-8 and otherwise non-sensical
2818
    /// content.
2819
    ///
2820
    /// Note that this is equivalent to the generic `[u8]::reverse` method.
2821
    /// This method is provided to permit callers to explicitly differentiate
2822
    /// between reversing bytes, codepoints and graphemes.
2823
    ///
2824
    /// # Examples
2825
    ///
2826
    /// Basic usage:
2827
    ///
2828
    /// ```
2829
    /// use bstr::ByteSlice;
2830
    ///
2831
    /// let mut s = <Vec<u8>>::from("hello");
2832
    /// s.reverse_bytes();
2833
    /// assert_eq!(s, "olleh".as_bytes());
2834
    /// ```
2835
    #[inline]
2836
0
    fn reverse_bytes(&mut self) {
2837
0
        self.as_bytes_mut().reverse();
2838
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_bytes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_bytes
2839
2840
    /// Reverse the codepoints in this string, in place.
2841
    ///
2842
    /// If this byte string is valid UTF-8, then its reversal by codepoint
2843
    /// is also guaranteed to be valid UTF-8.
2844
    ///
2845
    /// This operation is equivalent to the following, but without allocating:
2846
    ///
2847
    /// ```
2848
    /// use bstr::ByteSlice;
2849
    ///
2850
    /// let mut s = <Vec<u8>>::from("foo☃bar");
2851
    ///
2852
    /// let mut chars: Vec<char> = s.chars().collect();
2853
    /// chars.reverse();
2854
    ///
2855
    /// let reversed: String = chars.into_iter().collect();
2856
    /// assert_eq!(reversed, "rab☃oof");
2857
    /// ```
2858
    ///
2859
    /// Note that this is not necessarily a well formed operation. For example,
2860
    /// if this byte string contains grapheme clusters with more than one
2861
    /// codepoint, then those grapheme clusters will not necessarily be
2862
    /// preserved. If you'd like to preserve grapheme clusters, then use
2863
    /// [`reverse_graphemes`](#method.reverse_graphemes) instead.
2864
    ///
2865
    /// # Examples
2866
    ///
2867
    /// Basic usage:
2868
    ///
2869
    /// ```
2870
    /// use bstr::ByteSlice;
2871
    ///
2872
    /// let mut s = <Vec<u8>>::from("foo☃bar");
2873
    /// s.reverse_chars();
2874
    /// assert_eq!(s, "rab☃oof".as_bytes());
2875
    /// ```
2876
    ///
2877
    /// This example shows that not all reversals lead to a well formed string.
2878
    /// For example, in this case, combining marks are used to put accents over
2879
    /// some letters, and those accent marks must appear after the codepoints
2880
    /// they modify.
2881
    ///
2882
    /// ```
2883
    /// use bstr::{B, ByteSlice};
2884
    ///
2885
    /// let mut s = <Vec<u8>>::from("résumé");
2886
    /// s.reverse_chars();
2887
    /// assert_eq!(s, B(b"\xCC\x81emus\xCC\x81er"));
2888
    /// ```
2889
    ///
2890
    /// A word of warning: the above example relies on the fact that
2891
    /// `résumé` is in decomposed normal form, which means there are separate
2892
    /// codepoints for the accents above `e`. If it is instead in composed
2893
    /// normal form, then the example works:
2894
    ///
2895
    /// ```
2896
    /// use bstr::{B, ByteSlice};
2897
    ///
2898
    /// let mut s = <Vec<u8>>::from("résumé");
2899
    /// s.reverse_chars();
2900
    /// assert_eq!(s, B("émusér"));
2901
    /// ```
2902
    ///
2903
    /// The point here is to be cautious and not assume that just because
2904
    /// `reverse_chars` works in one case, that it therefore works in all
2905
    /// cases.
2906
    #[inline]
2907
0
    fn reverse_chars(&mut self) {
2908
0
        let mut i = 0;
2909
        loop {
2910
0
            let (_, size) = utf8::decode(&self.as_bytes()[i..]);
2911
0
            if size == 0 {
2912
0
                break;
2913
0
            }
2914
0
            if size > 1 {
2915
0
                self.as_bytes_mut()[i..i + size].reverse_bytes();
2916
0
            }
2917
0
            i += size;
2918
        }
2919
0
        self.reverse_bytes();
2920
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_chars
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_chars
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_chars
2921
2922
    /// Reverse the graphemes in this string, in place.
2923
    ///
2924
    /// If this byte string is valid UTF-8, then its reversal by grapheme
2925
    /// is also guaranteed to be valid UTF-8.
2926
    ///
2927
    /// This operation is equivalent to the following, but without allocating:
2928
    ///
2929
    /// ```
2930
    /// use bstr::ByteSlice;
2931
    ///
2932
    /// let mut s = <Vec<u8>>::from("foo☃bar");
2933
    ///
2934
    /// let mut graphemes: Vec<&str> = s.graphemes().collect();
2935
    /// graphemes.reverse();
2936
    ///
2937
    /// let reversed = graphemes.concat();
2938
    /// assert_eq!(reversed, "rab☃oof");
2939
    /// ```
2940
    ///
2941
    /// # Examples
2942
    ///
2943
    /// Basic usage:
2944
    ///
2945
    /// ```
2946
    /// use bstr::ByteSlice;
2947
    ///
2948
    /// let mut s = <Vec<u8>>::from("foo☃bar");
2949
    /// s.reverse_graphemes();
2950
    /// assert_eq!(s, "rab☃oof".as_bytes());
2951
    /// ```
2952
    ///
2953
    /// This example shows how this correctly handles grapheme clusters,
2954
    /// unlike `reverse_chars`.
2955
    ///
2956
    /// ```
2957
    /// use bstr::ByteSlice;
2958
    ///
2959
    /// let mut s = <Vec<u8>>::from("résumé");
2960
    /// s.reverse_graphemes();
2961
    /// assert_eq!(s, "émusér".as_bytes());
2962
    /// ```
2963
    #[cfg(feature = "unicode")]
2964
    #[inline]
2965
0
    fn reverse_graphemes(&mut self) {
2966
        use crate::unicode::decode_grapheme;
2967
2968
0
        let mut i = 0;
2969
        loop {
2970
0
            let (_, size) = decode_grapheme(&self.as_bytes()[i..]);
2971
0
            if size == 0 {
2972
0
                break;
2973
0
            }
2974
0
            if size > 1 {
2975
0
                self.as_bytes_mut()[i..i + size].reverse_bytes();
2976
0
            }
2977
0
            i += size;
2978
        }
2979
0
        self.reverse_bytes();
2980
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_graphemes
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::reverse_graphemes
2981
2982
    /// Returns true if and only if every byte in this byte string is ASCII.
2983
    ///
2984
    /// ASCII is an encoding that defines 128 codepoints. A byte corresponds to
2985
    /// an ASCII codepoint if and only if it is in the inclusive range
2986
    /// `[0, 127]`.
2987
    ///
2988
    /// # Examples
2989
    ///
2990
    /// Basic usage:
2991
    ///
2992
    /// ```
2993
    /// use bstr::{B, ByteSlice};
2994
    ///
2995
    /// assert!(B("abc").is_ascii());
2996
    /// assert!(!B("☃βツ").is_ascii());
2997
    /// assert!(!B(b"\xFF").is_ascii());
2998
    /// ```
2999
    #[inline]
3000
0
    fn is_ascii(&self) -> bool {
3001
0
        ascii::first_non_ascii_byte(self.as_bytes()) == self.as_bytes().len()
3002
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_ascii
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_ascii
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_ascii
3003
3004
    /// Returns true if and only if the entire byte string is valid UTF-8.
3005
    ///
3006
    /// If you need location information about where a byte string's first
3007
    /// invalid UTF-8 byte is, then use the [`to_str`](#method.to_str) method.
3008
    ///
3009
    /// # Examples
3010
    ///
3011
    /// Basic usage:
3012
    ///
3013
    /// ```
3014
    /// use bstr::{B, ByteSlice};
3015
    ///
3016
    /// assert!(B("abc").is_utf8());
3017
    /// assert!(B("☃βツ").is_utf8());
3018
    /// // invalid bytes
3019
    /// assert!(!B(b"abc\xFF").is_utf8());
3020
    /// // surrogate encoding
3021
    /// assert!(!B(b"\xED\xA0\x80").is_utf8());
3022
    /// // incomplete sequence
3023
    /// assert!(!B(b"\xF0\x9D\x9Ca").is_utf8());
3024
    /// // overlong sequence
3025
    /// assert!(!B(b"\xF0\x82\x82\xAC").is_utf8());
3026
    /// ```
3027
    #[inline]
3028
9.40k
    fn is_utf8(&self) -> bool {
3029
9.40k
        utf8::validate(self.as_bytes()).is_ok()
3030
9.40k
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_utf8
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_utf8
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::is_utf8
<[u8] as bstr::ext_slice::ByteSlice>::is_utf8
Line
Count
Source
3028
9.40k
    fn is_utf8(&self) -> bool {
3029
9.40k
        utf8::validate(self.as_bytes()).is_ok()
3030
9.40k
    }
3031
3032
    /// Returns the last byte in this byte string, if it's non-empty. If this
3033
    /// byte string is empty, this returns `None`.
3034
    ///
3035
    /// Note that this is like the generic `[u8]::last`, except this returns
3036
    /// the byte by value instead of a reference to the byte.
3037
    ///
3038
    /// # Examples
3039
    ///
3040
    /// Basic usage:
3041
    ///
3042
    /// ```
3043
    /// use bstr::ByteSlice;
3044
    ///
3045
    /// assert_eq!(Some(b'z'), b"baz".last_byte());
3046
    /// assert_eq!(None, b"".last_byte());
3047
    /// ```
3048
    #[inline]
3049
13.4M
    fn last_byte(&self) -> Option<u8> {
3050
13.4M
        let bytes = self.as_bytes();
3051
13.4M
        bytes.last().copied()
3052
13.4M
    }
<[u8] as bstr::ext_slice::ByteSlice>::last_byte
Line
Count
Source
3049
10.3M
    fn last_byte(&self) -> Option<u8> {
3050
10.3M
        let bytes = self.as_bytes();
3051
10.3M
        bytes.last().copied()
3052
10.3M
    }
<[u8] as bstr::ext_slice::ByteSlice>::last_byte
Line
Count
Source
3049
3.08M
    fn last_byte(&self) -> Option<u8> {
3050
3.08M
        let bytes = self.as_bytes();
3051
3.08M
        bytes.last().copied()
3052
3.08M
    }
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::last_byte
Unexecuted instantiation: <[u8] as bstr::ext_slice::ByteSlice>::last_byte
3053
3054
    /// Returns the index of the first non-ASCII byte in this byte string (if
3055
    /// any such indices exist). Specifically, it returns the index of the
3056
    /// first byte with a value greater than or equal to `0x80`.
3057
    ///
3058
    /// # Examples
3059
    ///
3060
    /// Basic usage:
3061
    ///
3062
    /// ```
3063
    /// use bstr::{ByteSlice, B};
3064
    ///
3065
    /// assert_eq!(Some(3), b"abc\xff".find_non_ascii_byte());
3066
    /// assert_eq!(None, b"abcde".find_non_ascii_byte());
3067
    /// assert_eq!(Some(0), B("😀").find_non_ascii_byte());
3068
    /// ```
3069
    #[inline]
3070
0
    fn find_non_ascii_byte(&self) -> Option<usize> {
3071
0
        let index = ascii::first_non_ascii_byte(self.as_bytes());
3072
0
        if index == self.as_bytes().len() {
3073
0
            None
3074
        } else {
3075
0
            Some(index)
3076
        }
3077
0
    }
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_non_ascii_byte
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_non_ascii_byte
Unexecuted instantiation: <_ as bstr::ext_slice::ByteSlice>::find_non_ascii_byte
3078
}
3079
3080
/// A single substring searcher fixed to a particular needle.
3081
///
3082
/// The purpose of this type is to permit callers to construct a substring
3083
/// searcher that can be used to search haystacks without the overhead of
3084
/// constructing the searcher in the first place. This is a somewhat niche
3085
/// concern when it's necessary to reuse the same needle to search multiple
3086
/// different haystacks with as little overhead as possible. In general, using
3087
/// [`ByteSlice::find`](trait.ByteSlice.html#method.find)
3088
/// or
3089
/// [`ByteSlice::find_iter`](trait.ByteSlice.html#method.find_iter)
3090
/// is good enough, but `Finder` is useful when you can meaningfully observe
3091
/// searcher construction time in a profile.
3092
///
3093
/// When the `std` feature is enabled, then this type has an `into_owned`
3094
/// version which permits building a `Finder` that is not connected to the
3095
/// lifetime of its needle.
3096
#[derive(Clone, Debug)]
3097
pub struct Finder<'a>(memmem::Finder<'a>);
3098
3099
impl<'a> Finder<'a> {
3100
    /// Create a new finder for the given needle.
3101
    #[inline]
3102
2.09M
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
2.09M
        Finder(memmem::Finder::new(needle.as_ref()))
3104
2.09M
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<_>
<bstr::ext_slice::Finder>::new::<[u8]>
Line
Count
Source
3102
2.07M
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
2.07M
        Finder(memmem::Finder::new(needle.as_ref()))
3104
2.07M
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<_>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<_>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
<bstr::ext_slice::Finder>::new::<[u8]>
Line
Count
Source
3102
2.66k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
2.66k
        Finder(memmem::Finder::new(needle.as_ref()))
3104
2.66k
    }
<bstr::ext_slice::Finder>::new::<[u8]>
Line
Count
Source
3102
10.4k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
10.4k
        Finder(memmem::Finder::new(needle.as_ref()))
3104
10.4k
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
<bstr::ext_slice::Finder>::new::<[u8]>
Line
Count
Source
3102
6.25k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
6.25k
        Finder(memmem::Finder::new(needle.as_ref()))
3104
6.25k
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::new::<[u8]>
<bstr::ext_slice::Finder>::new::<[u8]>
Line
Count
Source
3102
4.04k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103
4.04k
        Finder(memmem::Finder::new(needle.as_ref()))
3104
4.04k
    }
3105
3106
    /// Convert this finder into its owned variant, such that it no longer
3107
    /// borrows the needle.
3108
    ///
3109
    /// If this is already an owned finder, then this is a no-op. Otherwise,
3110
    /// this copies the needle.
3111
    ///
3112
    /// This is only available when the `alloc` feature is enabled.
3113
    #[cfg(feature = "alloc")]
3114
    #[inline]
3115
0
    pub fn into_owned(self) -> Finder<'static> {
3116
0
        Finder(self.0.into_owned())
3117
0
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::into_owned
Unexecuted instantiation: <bstr::ext_slice::Finder>::into_owned
Unexecuted instantiation: <bstr::ext_slice::Finder>::into_owned
3118
3119
    /// Returns the needle that this finder searches for.
3120
    ///
3121
    /// Note that the lifetime of the needle returned is tied to the lifetime
3122
    /// of the finder, and may be shorter than the `'a` lifetime. Namely, a
3123
    /// finder's needle can be either borrowed or owned, so the lifetime of the
3124
    /// needle returned must necessarily be the shorter of the two.
3125
    #[inline]
3126
0
    pub fn needle(&self) -> &[u8] {
3127
0
        self.0.needle()
3128
0
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::needle
Unexecuted instantiation: <bstr::ext_slice::Finder>::needle
Unexecuted instantiation: <bstr::ext_slice::Finder>::needle
3129
3130
    /// Returns the index of the first occurrence of this needle in the given
3131
    /// haystack.
3132
    ///
3133
    /// The haystack may be any type that can be cheaply converted into a
3134
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
3135
    ///
3136
    /// # Complexity
3137
    ///
3138
    /// This routine is guaranteed to have worst case linear time complexity
3139
    /// with respect to both the needle and the haystack. That is, this runs
3140
    /// in `O(needle.len() + haystack.len())` time.
3141
    ///
3142
    /// This routine is also guaranteed to have worst case constant space
3143
    /// complexity.
3144
    ///
3145
    /// # Examples
3146
    ///
3147
    /// Basic usage:
3148
    ///
3149
    /// ```
3150
    /// use bstr::Finder;
3151
    ///
3152
    /// let haystack = "foo bar baz";
3153
    /// assert_eq!(Some(0), Finder::new("foo").find(haystack));
3154
    /// assert_eq!(Some(4), Finder::new("bar").find(haystack));
3155
    /// assert_eq!(None, Finder::new("quux").find(haystack));
3156
    /// ```
3157
    #[inline]
3158
2.09M
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
2.09M
        self.0.find(haystack.as_ref())
3160
2.09M
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<_>
<bstr::ext_slice::Finder>::find::<&[u8]>
Line
Count
Source
3158
2.07M
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
2.07M
        self.0.find(haystack.as_ref())
3160
2.07M
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<_>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<_>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
<bstr::ext_slice::Finder>::find::<&[u8]>
Line
Count
Source
3158
2.66k
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
2.66k
        self.0.find(haystack.as_ref())
3160
2.66k
    }
<bstr::ext_slice::Finder>::find::<&[u8]>
Line
Count
Source
3158
10.4k
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
10.4k
        self.0.find(haystack.as_ref())
3160
10.4k
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
<bstr::ext_slice::Finder>::find::<&[u8]>
Line
Count
Source
3158
6.25k
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
6.25k
        self.0.find(haystack.as_ref())
3160
6.25k
    }
Unexecuted instantiation: <bstr::ext_slice::Finder>::find::<&[u8]>
<bstr::ext_slice::Finder>::find::<&[u8]>
Line
Count
Source
3158
4.04k
    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159
4.04k
        self.0.find(haystack.as_ref())
3160
4.04k
    }
3161
}
3162
3163
/// A single substring reverse searcher fixed to a particular needle.
3164
///
3165
/// The purpose of this type is to permit callers to construct a substring
3166
/// searcher that can be used to search haystacks without the overhead of
3167
/// constructing the searcher in the first place. This is a somewhat niche
3168
/// concern when it's necessary to re-use the same needle to search multiple
3169
/// different haystacks with as little overhead as possible. In general, using
3170
/// [`ByteSlice::rfind`](trait.ByteSlice.html#method.rfind)
3171
/// or
3172
/// [`ByteSlice::rfind_iter`](trait.ByteSlice.html#method.rfind_iter)
3173
/// is good enough, but `FinderReverse` is useful when you can meaningfully
3174
/// observe searcher construction time in a profile.
3175
///
3176
/// When the `std` feature is enabled, then this type has an `into_owned`
3177
/// version which permits building a `FinderReverse` that is not connected to
3178
/// the lifetime of its needle.
3179
#[derive(Clone, Debug)]
3180
pub struct FinderReverse<'a>(memmem::FinderRev<'a>);
3181
3182
impl<'a> FinderReverse<'a> {
3183
    /// Create a new reverse finder for the given needle.
3184
    #[inline]
3185
78.6k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a> {
3186
78.6k
        FinderReverse(memmem::FinderRev::new(needle.as_ref()))
3187
78.6k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<_>
<bstr::ext_slice::FinderReverse>::new::<[u8]>
Line
Count
Source
3185
71.7k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a> {
3186
71.7k
        FinderReverse(memmem::FinderRev::new(needle.as_ref()))
3187
71.7k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<_>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<_>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<[u8]>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<[u8]>
<bstr::ext_slice::FinderReverse>::new::<[u8]>
Line
Count
Source
3185
6.92k
    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a> {
3186
6.92k
        FinderReverse(memmem::FinderRev::new(needle.as_ref()))
3187
6.92k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::new::<[u8]>
3188
3189
    /// Convert this finder into its owned variant, such that it no longer
3190
    /// borrows the needle.
3191
    ///
3192
    /// If this is already an owned finder, then this is a no-op. Otherwise,
3193
    /// this copies the needle.
3194
    ///
3195
    /// This is only available when the `alloc` feature is enabled.
3196
    #[cfg(feature = "alloc")]
3197
    #[inline]
3198
0
    pub fn into_owned(self) -> FinderReverse<'static> {
3199
0
        FinderReverse(self.0.into_owned())
3200
0
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::into_owned
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::into_owned
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::into_owned
3201
3202
    /// Returns the needle that this finder searches for.
3203
    ///
3204
    /// Note that the lifetime of the needle returned is tied to the lifetime
3205
    /// of this finder, and may be shorter than the `'a` lifetime. Namely,
3206
    /// a finder's needle can be either borrowed or owned, so the lifetime of
3207
    /// the needle returned must necessarily be the shorter of the two.
3208
    #[inline]
3209
0
    pub fn needle(&self) -> &[u8] {
3210
0
        self.0.needle()
3211
0
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::needle
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::needle
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::needle
3212
3213
    /// Returns the index of the last occurrence of this needle in the given
3214
    /// haystack.
3215
    ///
3216
    /// The haystack may be any type that can be cheaply converted into a
3217
    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
3218
    ///
3219
    /// # Complexity
3220
    ///
3221
    /// This routine is guaranteed to have worst case linear time complexity
3222
    /// with respect to both the needle and the haystack. That is, this runs
3223
    /// in `O(needle.len() + haystack.len())` time.
3224
    ///
3225
    /// This routine is also guaranteed to have worst case constant space
3226
    /// complexity.
3227
    ///
3228
    /// # Examples
3229
    ///
3230
    /// Basic usage:
3231
    ///
3232
    /// ```
3233
    /// use bstr::FinderReverse;
3234
    ///
3235
    /// let haystack = "foo bar baz";
3236
    /// assert_eq!(Some(0), FinderReverse::new("foo").rfind(haystack));
3237
    /// assert_eq!(Some(4), FinderReverse::new("bar").rfind(haystack));
3238
    /// assert_eq!(None, FinderReverse::new("quux").rfind(haystack));
3239
    /// ```
3240
    #[inline]
3241
78.6k
    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3242
78.6k
        self.0.rfind(haystack.as_ref())
3243
78.6k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<_>
<bstr::ext_slice::FinderReverse>::rfind::<&[u8]>
Line
Count
Source
3241
71.7k
    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3242
71.7k
        self.0.rfind(haystack.as_ref())
3243
71.7k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<_>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<_>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<&[u8]>
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<&[u8]>
<bstr::ext_slice::FinderReverse>::rfind::<&[u8]>
Line
Count
Source
3241
6.92k
    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3242
6.92k
        self.0.rfind(haystack.as_ref())
3243
6.92k
    }
Unexecuted instantiation: <bstr::ext_slice::FinderReverse>::rfind::<&[u8]>
3244
}
3245
3246
/// An iterator over non-overlapping substring matches.
3247
///
3248
/// Matches are reported by the byte offset at which they begin.
3249
///
3250
/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
3251
/// needle.
3252
#[derive(Clone, Debug)]
3253
pub struct Find<'h, 'n> {
3254
    it: memmem::FindIter<'h, 'n>,
3255
    haystack: &'h [u8],
3256
    needle: &'n [u8],
3257
}
3258
3259
impl<'h, 'n> Find<'h, 'n> {
3260
2.53k
    fn new(haystack: &'h [u8], needle: &'n [u8]) -> Find<'h, 'n> {
3261
2.53k
        Find { it: memmem::find_iter(haystack, needle), haystack, needle }
3262
2.53k
    }
Unexecuted instantiation: <bstr::ext_slice::Find>::new
<bstr::ext_slice::Find>::new
Line
Count
Source
3260
2.53k
    fn new(haystack: &'h [u8], needle: &'n [u8]) -> Find<'h, 'n> {
3261
2.53k
        Find { it: memmem::find_iter(haystack, needle), haystack, needle }
3262
2.53k
    }
Unexecuted instantiation: <bstr::ext_slice::Find>::new
3263
}
3264
3265
impl<'h, 'n> Iterator for Find<'h, 'n> {
3266
    type Item = usize;
3267
3268
    #[inline]
3269
13.9M
    fn next(&mut self) -> Option<usize> {
3270
13.9M
        self.it.next()
3271
13.9M
    }
Unexecuted instantiation: <bstr::ext_slice::Find as core::iter::traits::iterator::Iterator>::next
<bstr::ext_slice::Find as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3269
13.9M
    fn next(&mut self) -> Option<usize> {
3270
13.9M
        self.it.next()
3271
13.9M
    }
Unexecuted instantiation: <bstr::ext_slice::Find as core::iter::traits::iterator::Iterator>::next
3272
}
3273
3274
/// An iterator over non-overlapping substring matches in reverse.
3275
///
3276
/// Matches are reported by the byte offset at which they begin.
3277
///
3278
/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
3279
/// needle.
3280
#[derive(Clone, Debug)]
3281
pub struct FindReverse<'h, 'n> {
3282
    it: memmem::FindRevIter<'h, 'n>,
3283
    haystack: &'h [u8],
3284
    needle: &'n [u8],
3285
}
3286
3287
impl<'h, 'n> FindReverse<'h, 'n> {
3288
0
    fn new(haystack: &'h [u8], needle: &'n [u8]) -> FindReverse<'h, 'n> {
3289
0
        FindReverse {
3290
0
            it: memmem::rfind_iter(haystack, needle),
3291
0
            haystack,
3292
0
            needle,
3293
0
        }
3294
0
    }
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::new
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::new
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::new
3295
3296
0
    fn haystack(&self) -> &'h [u8] {
3297
0
        self.haystack
3298
0
    }
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::haystack
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::haystack
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::haystack
3299
3300
0
    fn needle(&self) -> &'n [u8] {
3301
0
        self.needle
3302
0
    }
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::needle
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::needle
Unexecuted instantiation: <bstr::ext_slice::FindReverse>::needle
3303
}
3304
3305
impl<'h, 'n> Iterator for FindReverse<'h, 'n> {
3306
    type Item = usize;
3307
3308
    #[inline]
3309
0
    fn next(&mut self) -> Option<usize> {
3310
0
        self.it.next()
3311
0
    }
Unexecuted instantiation: <bstr::ext_slice::FindReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::FindReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::FindReverse as core::iter::traits::iterator::Iterator>::next
3312
}
3313
3314
/// An iterator over the bytes in a byte string.
3315
///
3316
/// `'a` is the lifetime of the byte string being traversed.
3317
#[derive(Clone, Debug)]
3318
pub struct Bytes<'a> {
3319
    it: slice::Iter<'a, u8>,
3320
}
3321
3322
impl<'a> Bytes<'a> {
3323
    /// Views the remaining underlying data as a subslice of the original data.
3324
    /// This has the same lifetime as the original slice,
3325
    /// and so the iterator can continue to be used while this exists.
3326
    #[inline]
3327
0
    pub fn as_bytes(&self) -> &'a [u8] {
3328
0
        self.it.as_slice()
3329
0
    }
Unexecuted instantiation: <bstr::ext_slice::Bytes>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::Bytes>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::Bytes>::as_bytes
3330
}
3331
3332
impl<'a> Iterator for Bytes<'a> {
3333
    type Item = u8;
3334
3335
    #[inline]
3336
33.7M
    fn next(&mut self) -> Option<u8> {
3337
33.7M
        self.it.next().copied()
3338
33.7M
    }
<bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3336
22.8k
    fn next(&mut self) -> Option<u8> {
3337
22.8k
        self.it.next().copied()
3338
22.8k
    }
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::next
<bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3336
33.6M
    fn next(&mut self) -> Option<u8> {
3337
33.6M
        self.it.next().copied()
3338
33.6M
    }
3339
3340
    #[inline]
3341
0
    fn size_hint(&self) -> (usize, Option<usize>) {
3342
0
        self.it.size_hint()
3343
0
    }
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::size_hint
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::size_hint
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::iterator::Iterator>::size_hint
3344
}
3345
3346
impl<'a> DoubleEndedIterator for Bytes<'a> {
3347
    #[inline]
3348
0
    fn next_back(&mut self) -> Option<u8> {
3349
0
        self.it.next_back().copied()
3350
0
    }
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
3351
}
3352
3353
impl<'a> ExactSizeIterator for Bytes<'a> {
3354
    #[inline]
3355
0
    fn len(&self) -> usize {
3356
0
        self.it.len()
3357
0
    }
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::exact_size::ExactSizeIterator>::len
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::exact_size::ExactSizeIterator>::len
Unexecuted instantiation: <bstr::ext_slice::Bytes as core::iter::traits::exact_size::ExactSizeIterator>::len
3358
}
3359
3360
impl<'a> iter::FusedIterator for Bytes<'a> {}
3361
3362
/// An iterator over the fields in a byte string, separated by whitespace.
3363
///
3364
/// Whitespace for this iterator is defined by the Unicode property
3365
/// `White_Space`.
3366
///
3367
/// This iterator splits on contiguous runs of whitespace, such that the fields
3368
/// in `foo\t\t\n  \nbar` are `foo` and `bar`.
3369
///
3370
/// `'a` is the lifetime of the byte string being split.
3371
#[cfg(feature = "unicode")]
3372
#[doc(alias = "SplitWhitespace")]
3373
#[derive(Clone, Debug)]
3374
pub struct Fields<'a> {
3375
    it: FieldsWith<'a, fn(char) -> bool>,
3376
}
3377
3378
#[cfg(feature = "unicode")]
3379
impl<'a> Fields<'a> {
3380
19.1k
    fn new(bytes: &'a [u8]) -> Fields<'a> {
3381
19.1k
        Fields { it: bytes.fields_with(char::is_whitespace) }
3382
19.1k
    }
<bstr::ext_slice::Fields>::new
Line
Count
Source
3380
19.1k
    fn new(bytes: &'a [u8]) -> Fields<'a> {
3381
19.1k
        Fields { it: bytes.fields_with(char::is_whitespace) }
3382
19.1k
    }
Unexecuted instantiation: <bstr::ext_slice::Fields>::new
3383
}
3384
3385
#[cfg(feature = "unicode")]
3386
impl<'a> Iterator for Fields<'a> {
3387
    type Item = &'a [u8];
3388
3389
    #[inline]
3390
0
    fn next(&mut self) -> Option<&'a [u8]> {
3391
0
        self.it.next()
3392
0
    }
Unexecuted instantiation: <bstr::ext_slice::Fields as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::Fields as core::iter::traits::iterator::Iterator>::next
3393
}
3394
3395
/// An iterator over fields in the byte string, separated by a predicate over
3396
/// codepoints.
3397
///
3398
/// This iterator splits a byte string based on its predicate function such
3399
/// that the elements returned are separated by contiguous runs of codepoints
3400
/// for which the predicate returns true.
3401
///
3402
/// `'a` is the lifetime of the byte string being split, while `F` is the type
3403
/// of the predicate, i.e., `FnMut(char) -> bool`.
3404
#[derive(Clone, Debug)]
3405
pub struct FieldsWith<'a, F> {
3406
    f: F,
3407
    bytes: &'a [u8],
3408
    chars: CharIndices<'a>,
3409
}
3410
3411
impl<'a, F: FnMut(char) -> bool> FieldsWith<'a, F> {
3412
19.1k
    fn new(bytes: &'a [u8], f: F) -> FieldsWith<'a, F> {
3413
19.1k
        FieldsWith { f, bytes, chars: bytes.char_indices() }
3414
19.1k
    }
<bstr::ext_slice::FieldsWith<fn(char) -> bool>>::new
Line
Count
Source
3412
19.1k
    fn new(bytes: &'a [u8], f: F) -> FieldsWith<'a, F> {
3413
19.1k
        FieldsWith { f, bytes, chars: bytes.char_indices() }
3414
19.1k
    }
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<fn(char) -> bool>>::new
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<_>>::new
3415
}
3416
3417
impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F> {
3418
    type Item = &'a [u8];
3419
3420
    #[inline]
3421
4.78M
    fn next(&mut self) -> Option<&'a [u8]> {
3422
        let (start, mut end);
3423
        loop {
3424
4.85M
            match self.chars.next() {
3425
16.7k
                None => return None,
3426
4.83M
                Some((s, e, ch)) => {
3427
4.83M
                    if !(self.f)(ch) {
3428
4.76M
                        start = s;
3429
4.76M
                        end = e;
3430
4.76M
                        break;
3431
70.8k
                    }
3432
                }
3433
            }
3434
        }
3435
64.5M
        for (_, e, ch) in self.chars.by_ref() {
3436
64.5M
            if (self.f)(ch) {
3437
4.75M
                break;
3438
59.8M
            }
3439
59.8M
            end = e;
3440
        }
3441
4.76M
        Some(&self.bytes[start..end])
3442
4.78M
    }
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<_> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<_> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<_> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::FieldsWith<fn(char) -> bool> as core::iter::traits::iterator::Iterator>::next
<bstr::ext_slice::FieldsWith<fn(char) -> bool> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3421
42.1k
    fn next(&mut self) -> Option<&'a [u8]> {
3422
        let (start, mut end);
3423
        loop {
3424
57.4k
            match self.chars.next() {
3425
13.8k
                None => return None,
3426
43.5k
                Some((s, e, ch)) => {
3427
43.5k
                    if !(self.f)(ch) {
3428
28.2k
                        start = s;
3429
28.2k
                        end = e;
3430
28.2k
                        break;
3431
15.2k
                    }
3432
                }
3433
            }
3434
        }
3435
71.1k
        for (_, e, ch) in self.chars.by_ref() {
3436
71.1k
            if (self.f)(ch) {
3437
19.6k
                break;
3438
51.4k
            }
3439
51.4k
            end = e;
3440
        }
3441
28.2k
        Some(&self.bytes[start..end])
3442
42.1k
    }
<bstr::ext_slice::FieldsWith<fn(char) -> bool> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3421
4.74M
    fn next(&mut self) -> Option<&'a [u8]> {
3422
        let (start, mut end);
3423
        loop {
3424
4.79M
            match self.chars.next() {
3425
2.89k
                None => return None,
3426
4.79M
                Some((s, e, ch)) => {
3427
4.79M
                    if !(self.f)(ch) {
3428
4.73M
                        start = s;
3429
4.73M
                        end = e;
3430
4.73M
                        break;
3431
55.5k
                    }
3432
                }
3433
            }
3434
        }
3435
64.5M
        for (_, e, ch) in self.chars.by_ref() {
3436
64.5M
            if (self.f)(ch) {
3437
4.73M
                break;
3438
59.7M
            }
3439
59.7M
            end = e;
3440
        }
3441
4.73M
        Some(&self.bytes[start..end])
3442
4.74M
    }
3443
}
3444
3445
/// An iterator over substrings in a byte string, split by a separator.
3446
///
3447
/// `'h` is the lifetime of the byte string being split (the haystack), while
3448
/// `'s` is the lifetime of the byte string doing the splitting.
3449
#[derive(Clone, Debug)]
3450
pub struct Split<'h, 's> {
3451
    finder: Find<'h, 's>,
3452
    /// The end position of the previous match of our splitter. The element
3453
    /// we yield corresponds to the substring starting at `last` up to the
3454
    /// beginning of the next match of the splitter.
3455
    last: usize,
3456
    /// Only set when iteration is complete. A corner case here is when a
3457
    /// splitter is matched at the end of the haystack. At that point, we still
3458
    /// need to yield an empty string following it.
3459
    done: bool,
3460
}
3461
3462
impl<'h, 's> Split<'h, 's> {
3463
2.53k
    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> Split<'h, 's> {
3464
2.53k
        let finder = haystack.find_iter(splitter);
3465
2.53k
        Split { finder, last: 0, done: false }
3466
2.53k
    }
Unexecuted instantiation: <bstr::ext_slice::Split>::new
<bstr::ext_slice::Split>::new
Line
Count
Source
3463
2.53k
    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> Split<'h, 's> {
3464
2.53k
        let finder = haystack.find_iter(splitter);
3465
2.53k
        Split { finder, last: 0, done: false }
3466
2.53k
    }
Unexecuted instantiation: <bstr::ext_slice::Split>::new
3467
}
3468
3469
impl<'h, 's> Iterator for Split<'h, 's> {
3470
    type Item = &'h [u8];
3471
3472
    #[inline]
3473
13.9M
    fn next(&mut self) -> Option<&'h [u8]> {
3474
13.9M
        let haystack = self.finder.haystack;
3475
13.9M
        match self.finder.next() {
3476
13.9M
            Some(start) => {
3477
13.9M
                let next = &haystack[self.last..start];
3478
13.9M
                self.last = start + self.finder.needle.len();
3479
13.9M
                Some(next)
3480
            }
3481
            None => {
3482
5.07k
                if self.last >= haystack.len() {
3483
2.60k
                    if !self.done {
3484
69
                        self.done = true;
3485
69
                        Some(b"")
3486
                    } else {
3487
2.53k
                        None
3488
                    }
3489
                } else {
3490
2.47k
                    let s = &haystack[self.last..];
3491
2.47k
                    self.last = haystack.len();
3492
2.47k
                    self.done = true;
3493
2.47k
                    Some(s)
3494
                }
3495
            }
3496
        }
3497
13.9M
    }
Unexecuted instantiation: <bstr::ext_slice::Split as core::iter::traits::iterator::Iterator>::next
<bstr::ext_slice::Split as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3473
13.9M
    fn next(&mut self) -> Option<&'h [u8]> {
3474
13.9M
        let haystack = self.finder.haystack;
3475
13.9M
        match self.finder.next() {
3476
13.9M
            Some(start) => {
3477
13.9M
                let next = &haystack[self.last..start];
3478
13.9M
                self.last = start + self.finder.needle.len();
3479
13.9M
                Some(next)
3480
            }
3481
            None => {
3482
5.07k
                if self.last >= haystack.len() {
3483
2.60k
                    if !self.done {
3484
69
                        self.done = true;
3485
69
                        Some(b"")
3486
                    } else {
3487
2.53k
                        None
3488
                    }
3489
                } else {
3490
2.47k
                    let s = &haystack[self.last..];
3491
2.47k
                    self.last = haystack.len();
3492
2.47k
                    self.done = true;
3493
2.47k
                    Some(s)
3494
                }
3495
            }
3496
        }
3497
13.9M
    }
Unexecuted instantiation: <bstr::ext_slice::Split as core::iter::traits::iterator::Iterator>::next
3498
}
3499
3500
/// An iterator over substrings in a byte string, split by a separator, in
3501
/// reverse.
3502
///
3503
/// `'h` is the lifetime of the byte string being split (the haystack), while
3504
/// `'s` is the lifetime of the byte string doing the splitting.
3505
#[derive(Clone, Debug)]
3506
pub struct SplitReverse<'h, 's> {
3507
    finder: FindReverse<'h, 's>,
3508
    /// The end position of the previous match of our splitter. The element
3509
    /// we yield corresponds to the substring starting at `last` up to the
3510
    /// beginning of the next match of the splitter.
3511
    last: usize,
3512
    /// Only set when iteration is complete. A corner case here is when a
3513
    /// splitter is matched at the end of the haystack. At that point, we still
3514
    /// need to yield an empty string following it.
3515
    done: bool,
3516
}
3517
3518
impl<'h, 's> SplitReverse<'h, 's> {
3519
0
    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> SplitReverse<'h, 's> {
3520
0
        let finder = haystack.rfind_iter(splitter);
3521
0
        SplitReverse { finder, last: haystack.len(), done: false }
3522
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitReverse>::new
Unexecuted instantiation: <bstr::ext_slice::SplitReverse>::new
Unexecuted instantiation: <bstr::ext_slice::SplitReverse>::new
3523
}
3524
3525
impl<'h, 's> Iterator for SplitReverse<'h, 's> {
3526
    type Item = &'h [u8];
3527
3528
    #[inline]
3529
0
    fn next(&mut self) -> Option<&'h [u8]> {
3530
0
        let haystack = self.finder.haystack();
3531
0
        match self.finder.next() {
3532
0
            Some(start) => {
3533
0
                let nlen = self.finder.needle().len();
3534
0
                let next = &haystack[start + nlen..self.last];
3535
0
                self.last = start;
3536
0
                Some(next)
3537
            }
3538
            None => {
3539
0
                if self.last == 0 {
3540
0
                    if !self.done {
3541
0
                        self.done = true;
3542
0
                        Some(b"")
3543
                    } else {
3544
0
                        None
3545
                    }
3546
                } else {
3547
0
                    let s = &haystack[..self.last];
3548
0
                    self.last = 0;
3549
0
                    self.done = true;
3550
0
                    Some(s)
3551
                }
3552
            }
3553
        }
3554
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitReverse as core::iter::traits::iterator::Iterator>::next
3555
}
3556
3557
/// An iterator over at most `n` substrings in a byte string, split by a
3558
/// separator.
3559
///
3560
/// `'h` is the lifetime of the byte string being split (the haystack), while
3561
/// `'s` is the lifetime of the byte string doing the splitting.
3562
#[derive(Clone, Debug)]
3563
pub struct SplitN<'h, 's> {
3564
    split: Split<'h, 's>,
3565
    limit: usize,
3566
    count: usize,
3567
}
3568
3569
impl<'h, 's> SplitN<'h, 's> {
3570
0
    fn new(
3571
0
        haystack: &'h [u8],
3572
0
        splitter: &'s [u8],
3573
0
        limit: usize,
3574
0
    ) -> SplitN<'h, 's> {
3575
0
        let split = haystack.split_str(splitter);
3576
0
        SplitN { split, limit, count: 0 }
3577
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitN>::new
Unexecuted instantiation: <bstr::ext_slice::SplitN>::new
Unexecuted instantiation: <bstr::ext_slice::SplitN>::new
3578
}
3579
3580
impl<'h, 's> Iterator for SplitN<'h, 's> {
3581
    type Item = &'h [u8];
3582
3583
    #[inline]
3584
0
    fn next(&mut self) -> Option<&'h [u8]> {
3585
0
        self.count += 1;
3586
0
        if self.count > self.limit || self.split.done {
3587
0
            None
3588
0
        } else if self.count == self.limit {
3589
0
            Some(&self.split.finder.haystack[self.split.last..])
3590
        } else {
3591
0
            self.split.next()
3592
        }
3593
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitN as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitN as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitN as core::iter::traits::iterator::Iterator>::next
3594
}
3595
3596
/// An iterator over at most `n` substrings in a byte string, split by a
3597
/// separator, in reverse.
3598
///
3599
/// `'h` is the lifetime of the byte string being split (the haystack), while
3600
/// `'s` is the lifetime of the byte string doing the splitting.
3601
#[derive(Clone, Debug)]
3602
pub struct SplitNReverse<'h, 's> {
3603
    split: SplitReverse<'h, 's>,
3604
    limit: usize,
3605
    count: usize,
3606
}
3607
3608
impl<'h, 's> SplitNReverse<'h, 's> {
3609
0
    fn new(
3610
0
        haystack: &'h [u8],
3611
0
        splitter: &'s [u8],
3612
0
        limit: usize,
3613
0
    ) -> SplitNReverse<'h, 's> {
3614
0
        let split = haystack.rsplit_str(splitter);
3615
0
        SplitNReverse { split, limit, count: 0 }
3616
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse>::new
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse>::new
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse>::new
3617
}
3618
3619
impl<'h, 's> Iterator for SplitNReverse<'h, 's> {
3620
    type Item = &'h [u8];
3621
3622
    #[inline]
3623
0
    fn next(&mut self) -> Option<&'h [u8]> {
3624
0
        self.count += 1;
3625
0
        if self.count > self.limit || self.split.done {
3626
0
            None
3627
0
        } else if self.count == self.limit {
3628
0
            Some(&self.split.finder.haystack()[..self.split.last])
3629
        } else {
3630
0
            self.split.next()
3631
        }
3632
0
    }
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bstr::ext_slice::SplitNReverse as core::iter::traits::iterator::Iterator>::next
3633
}
3634
3635
/// An iterator over all lines in a byte string, without their terminators.
3636
///
3637
/// For this iterator, the only line terminators recognized are `\r\n` and
3638
/// `\n`.
3639
///
3640
/// `'a` is the lifetime of the byte string being iterated over.
3641
#[derive(Clone, Debug)]
3642
pub struct Lines<'a> {
3643
    it: LinesWithTerminator<'a>,
3644
}
3645
3646
impl<'a> Lines<'a> {
3647
34.5k
    fn new(bytes: &'a [u8]) -> Lines<'a> {
3648
34.5k
        Lines { it: LinesWithTerminator::new(bytes) }
3649
34.5k
    }
<bstr::ext_slice::Lines>::new
Line
Count
Source
3647
32.4k
    fn new(bytes: &'a [u8]) -> Lines<'a> {
3648
32.4k
        Lines { it: LinesWithTerminator::new(bytes) }
3649
32.4k
    }
<bstr::ext_slice::Lines>::new
Line
Count
Source
3647
2.16k
    fn new(bytes: &'a [u8]) -> Lines<'a> {
3648
2.16k
        Lines { it: LinesWithTerminator::new(bytes) }
3649
2.16k
    }
Unexecuted instantiation: <bstr::ext_slice::Lines>::new
3650
3651
    /// Return a copy of the rest of the underlying bytes without affecting the
3652
    /// iterator itself.
3653
    ///
3654
    /// # Examples
3655
    ///
3656
    /// Basic usage:
3657
    ///
3658
    /// ```
3659
    /// use bstr::{B, ByteSlice};
3660
    ///
3661
    /// let s = b"\
3662
    /// foo
3663
    /// bar\r
3664
    /// baz";
3665
    /// let mut lines = s.lines();
3666
    /// assert_eq!(lines.next(), Some(B("foo")));
3667
    /// assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
3668
    /// ```
3669
0
    pub fn as_bytes(&self) -> &'a [u8] {
3670
0
        self.it.bytes
3671
0
    }
Unexecuted instantiation: <bstr::ext_slice::Lines>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::Lines>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::Lines>::as_bytes
3672
}
3673
3674
impl<'a> Iterator for Lines<'a> {
3675
    type Item = &'a [u8];
3676
3677
    #[inline]
3678
6.74M
    fn next(&mut self) -> Option<&'a [u8]> {
3679
6.74M
        Some(trim_last_terminator(self.it.next()?))
3680
6.74M
    }
<bstr::ext_slice::Lines as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3678
5.19M
    fn next(&mut self) -> Option<&'a [u8]> {
3679
5.19M
        Some(trim_last_terminator(self.it.next()?))
3680
5.19M
    }
<bstr::ext_slice::Lines as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3678
1.54M
    fn next(&mut self) -> Option<&'a [u8]> {
3679
1.54M
        Some(trim_last_terminator(self.it.next()?))
3680
1.54M
    }
Unexecuted instantiation: <bstr::ext_slice::Lines as core::iter::traits::iterator::Iterator>::next
3681
}
3682
3683
impl<'a> DoubleEndedIterator for Lines<'a> {
3684
    #[inline]
3685
0
    fn next_back(&mut self) -> Option<Self::Item> {
3686
0
        Some(trim_last_terminator(self.it.next_back()?))
3687
0
    }
Unexecuted instantiation: <bstr::ext_slice::Lines as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::Lines as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::Lines as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
3688
}
3689
3690
impl<'a> iter::FusedIterator for Lines<'a> {}
3691
3692
/// An iterator over all lines in a byte string, including their terminators.
3693
///
3694
/// For this iterator, the only line terminator recognized is `\n`. (Since
3695
/// line terminators are included, this also handles `\r\n` line endings.)
3696
///
3697
/// Line terminators are only included if they are present in the original
3698
/// byte string. For example, the last line in a byte string may not end with
3699
/// a line terminator.
3700
///
3701
/// Concatenating all elements yielded by this iterator is guaranteed to yield
3702
/// the original byte string.
3703
///
3704
/// `'a` is the lifetime of the byte string being iterated over.
3705
#[derive(Clone, Debug)]
3706
pub struct LinesWithTerminator<'a> {
3707
    bytes: &'a [u8],
3708
}
3709
3710
impl<'a> LinesWithTerminator<'a> {
3711
105k
    fn new(bytes: &'a [u8]) -> LinesWithTerminator<'a> {
3712
105k
        LinesWithTerminator { bytes }
3713
105k
    }
<bstr::ext_slice::LinesWithTerminator>::new
Line
Count
Source
3711
103k
    fn new(bytes: &'a [u8]) -> LinesWithTerminator<'a> {
3712
103k
        LinesWithTerminator { bytes }
3713
103k
    }
<bstr::ext_slice::LinesWithTerminator>::new
Line
Count
Source
3711
2.16k
    fn new(bytes: &'a [u8]) -> LinesWithTerminator<'a> {
3712
2.16k
        LinesWithTerminator { bytes }
3713
2.16k
    }
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator>::new
3714
3715
    /// Return a copy of the rest of the underlying bytes without affecting the
3716
    /// iterator itself.
3717
    ///
3718
    /// # Examples
3719
    ///
3720
    /// Basic usage:
3721
    ///
3722
    /// ```
3723
    /// use bstr::{B, ByteSlice};
3724
    ///
3725
    /// let s = b"\
3726
    /// foo
3727
    /// bar\r
3728
    /// baz";
3729
    /// let mut lines = s.lines_with_terminator();
3730
    /// assert_eq!(lines.next(), Some(B("foo\n")));
3731
    /// assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
3732
    /// ```
3733
0
    pub fn as_bytes(&self) -> &'a [u8] {
3734
0
        self.bytes
3735
0
    }
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator>::as_bytes
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator>::as_bytes
3736
}
3737
3738
impl<'a> Iterator for LinesWithTerminator<'a> {
3739
    type Item = &'a [u8];
3740
3741
    #[inline]
3742
8.36M
    fn next(&mut self) -> Option<&'a [u8]> {
3743
8.36M
        match self.bytes.find_byte(b'\n') {
3744
123k
            None if self.bytes.is_empty() => None,
3745
            None => {
3746
22.9k
                let line = self.bytes;
3747
22.9k
                self.bytes = b"";
3748
22.9k
                Some(line)
3749
            }
3750
8.24M
            Some(end) => {
3751
8.24M
                let line = &self.bytes[..=end];
3752
8.24M
                self.bytes = &self.bytes[end + 1..];
3753
8.24M
                Some(line)
3754
            }
3755
        }
3756
8.36M
    }
<bstr::ext_slice::LinesWithTerminator as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3742
6.82M
    fn next(&mut self) -> Option<&'a [u8]> {
3743
6.82M
        match self.bytes.find_byte(b'\n') {
3744
120k
            None if self.bytes.is_empty() => None,
3745
            None => {
3746
21.7k
                let line = self.bytes;
3747
21.7k
                self.bytes = b"";
3748
21.7k
                Some(line)
3749
            }
3750
6.70M
            Some(end) => {
3751
6.70M
                let line = &self.bytes[..=end];
3752
6.70M
                self.bytes = &self.bytes[end + 1..];
3753
6.70M
                Some(line)
3754
            }
3755
        }
3756
6.82M
    }
<bstr::ext_slice::LinesWithTerminator as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
3742
1.54M
    fn next(&mut self) -> Option<&'a [u8]> {
3743
1.54M
        match self.bytes.find_byte(b'\n') {
3744
3.25k
            None if self.bytes.is_empty() => None,
3745
            None => {
3746
1.22k
                let line = self.bytes;
3747
1.22k
                self.bytes = b"";
3748
1.22k
                Some(line)
3749
            }
3750
1.53M
            Some(end) => {
3751
1.53M
                let line = &self.bytes[..=end];
3752
1.53M
                self.bytes = &self.bytes[end + 1..];
3753
1.53M
                Some(line)
3754
            }
3755
        }
3756
1.54M
    }
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator as core::iter::traits::iterator::Iterator>::next
3757
}
3758
3759
impl<'a> DoubleEndedIterator for LinesWithTerminator<'a> {
3760
    #[inline]
3761
0
    fn next_back(&mut self) -> Option<Self::Item> {
3762
0
        let end = self.bytes.len().checked_sub(1)?;
3763
0
        match self.bytes[..end].rfind_byte(b'\n') {
3764
            None => {
3765
0
                let line = self.bytes;
3766
0
                self.bytes = b"";
3767
0
                Some(line)
3768
            }
3769
0
            Some(end) => {
3770
0
                let line = &self.bytes[end + 1..];
3771
0
                self.bytes = &self.bytes[..=end];
3772
0
                Some(line)
3773
            }
3774
        }
3775
0
    }
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
Unexecuted instantiation: <bstr::ext_slice::LinesWithTerminator as core::iter::traits::double_ended::DoubleEndedIterator>::next_back
3776
}
3777
3778
impl<'a> iter::FusedIterator for LinesWithTerminator<'a> {}
3779
3780
6.71M
fn trim_last_terminator(mut s: &[u8]) -> &[u8] {
3781
6.71M
    if s.last_byte() == Some(b'\n') {
3782
6.68M
        s = &s[..s.len() - 1];
3783
6.68M
        if s.last_byte() == Some(b'\r') {
3784
2.18k
            s = &s[..s.len() - 1];
3785
6.68M
        }
3786
22.9k
    }
3787
6.71M
    s
3788
6.71M
}
bstr::ext_slice::trim_last_terminator
Line
Count
Source
3780
5.17M
fn trim_last_terminator(mut s: &[u8]) -> &[u8] {
3781
5.17M
    if s.last_byte() == Some(b'\n') {
3782
5.14M
        s = &s[..s.len() - 1];
3783
5.14M
        if s.last_byte() == Some(b'\r') {
3784
291
            s = &s[..s.len() - 1];
3785
5.14M
        }
3786
21.7k
    }
3787
5.17M
    s
3788
5.17M
}
bstr::ext_slice::trim_last_terminator
Line
Count
Source
3780
1.54M
fn trim_last_terminator(mut s: &[u8]) -> &[u8] {
3781
1.54M
    if s.last_byte() == Some(b'\n') {
3782
1.53M
        s = &s[..s.len() - 1];
3783
1.53M
        if s.last_byte() == Some(b'\r') {
3784
1.89k
            s = &s[..s.len() - 1];
3785
1.53M
        }
3786
1.22k
    }
3787
1.54M
    s
3788
1.54M
}
Unexecuted instantiation: bstr::ext_slice::trim_last_terminator
3789
3790
#[cfg(all(test, feature = "std"))]
3791
mod tests {
3792
    use alloc::{string::String, vec::Vec};
3793
3794
    use crate::{
3795
        ext_slice::{ByteSlice, Lines, LinesWithTerminator, B},
3796
        tests::LOSSY_TESTS,
3797
    };
3798
3799
    #[test]
3800
    fn to_str_lossy() {
3801
        for (i, &(expected, input)) in LOSSY_TESTS.iter().enumerate() {
3802
            let got = B(input).to_str_lossy();
3803
            assert_eq!(
3804
                expected.as_bytes(),
3805
                got.as_bytes(),
3806
                "to_str_lossy(ith: {:?}, given: {:?})",
3807
                i,
3808
                input,
3809
            );
3810
3811
            let mut got = String::new();
3812
            B(input).to_str_lossy_into(&mut got);
3813
            assert_eq!(
3814
                expected.as_bytes(),
3815
                got.as_bytes(),
3816
                "to_str_lossy_into",
3817
            );
3818
3819
            let got = String::from_utf8_lossy(input);
3820
            assert_eq!(expected.as_bytes(), got.as_bytes(), "std");
3821
        }
3822
    }
3823
3824
    #[test]
3825
    fn lines_iteration() {
3826
        macro_rules! t {
3827
            ($it:expr, $forward:expr) => {
3828
                let mut res: Vec<&[u8]> = Vec::from($forward);
3829
                assert_eq!($it.collect::<Vec<_>>(), res);
3830
                res.reverse();
3831
                assert_eq!($it.rev().collect::<Vec<_>>(), res);
3832
            };
3833
        }
3834
3835
        t!(Lines::new(b""), []);
3836
        t!(LinesWithTerminator::new(b""), []);
3837
3838
        t!(Lines::new(b"\n"), [B("")]);
3839
        t!(Lines::new(b"\r\n"), [B("")]);
3840
        t!(LinesWithTerminator::new(b"\n"), [B("\n")]);
3841
3842
        t!(Lines::new(b"a"), [B("a")]);
3843
        t!(LinesWithTerminator::new(b"a"), [B("a")]);
3844
3845
        t!(Lines::new(b"abc"), [B("abc")]);
3846
        t!(LinesWithTerminator::new(b"abc"), [B("abc")]);
3847
3848
        t!(Lines::new(b"abc\n"), [B("abc")]);
3849
        t!(Lines::new(b"abc\r\n"), [B("abc")]);
3850
        t!(LinesWithTerminator::new(b"abc\n"), [B("abc\n")]);
3851
3852
        t!(Lines::new(b"abc\n\n"), [B("abc"), B("")]);
3853
        t!(LinesWithTerminator::new(b"abc\n\n"), [B("abc\n"), B("\n")]);
3854
3855
        t!(Lines::new(b"abc\n\ndef"), [B("abc"), B(""), B("def")]);
3856
        t!(
3857
            LinesWithTerminator::new(b"abc\n\ndef"),
3858
            [B("abc\n"), B("\n"), B("def")]
3859
        );
3860
3861
        t!(Lines::new(b"abc\n\ndef\n"), [B("abc"), B(""), B("def")]);
3862
        t!(
3863
            LinesWithTerminator::new(b"abc\n\ndef\n"),
3864
            [B("abc\n"), B("\n"), B("def\n")]
3865
        );
3866
3867
        t!(Lines::new(b"\na\nb\n"), [B(""), B("a"), B("b")]);
3868
        t!(
3869
            LinesWithTerminator::new(b"\na\nb\n"),
3870
            [B("\n"), B("a\n"), B("b\n")]
3871
        );
3872
3873
        t!(Lines::new(b"\n\n\n"), [B(""), B(""), B("")]);
3874
        t!(LinesWithTerminator::new(b"\n\n\n"), [B("\n"), B("\n"), B("\n")]);
3875
    }
3876
}