Skip to main content

bstr/
ext_slice.rs

1use core::{iter, slice, str};
2
3#[cfg(all(feature = "alloc", feature = "unicode"))]
4use alloc::vec;
5#[cfg(feature = "alloc")]
6use alloc::{borrow::Cow, string::String, vec::Vec};
7
8#[cfg(feature = "std")]
9use std::{ffi::OsStr, path::Path};
10
11use memchr::{memchr, memmem, memrchr};
12
13use crate::escape_bytes::EscapeBytes;
14#[cfg(feature = "alloc")]
15use crate::ext_vec::ByteVec;
16#[cfg(feature = "unicode")]
17use crate::unicode::{
18    whitespace_len_fwd, whitespace_len_rev, GraphemeIndices, Graphemes,
19    SentenceIndices, Sentences, WordIndices, Words, WordsWithBreakIndices,
20    WordsWithBreaks,
21};
22use 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]
75pub fn B<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &[u8] {
76    bytes.as_ref()
77}
78
79impl ByteSlice for [u8] {
80    #[inline]
81    fn as_bytes(&self) -> &[u8] {
82        self
83    }
84
85    #[inline]
86    fn as_bytes_mut(&mut self) -> &mut [u8] {
87        self
88    }
89}
90
91impl<const N: usize> ByteSlice for [u8; N] {
92    #[inline]
93    fn as_bytes(&self) -> &[u8] {
94        self
95    }
96
97    #[inline]
98    fn as_bytes_mut(&mut self) -> &mut [u8] {
99        self
100    }
101}
102
103/// Ensure that callers cannot implement `ByteSlice` by making an
104/// umplementable trait its super trait.
105mod private {
106    pub trait Sealed {}
107}
108impl private::Sealed for [u8] {}
109impl<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`.
114pub 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    /// `&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    fn as_bstr(&self) -> &BStr {
146        BStr::new(self.as_bytes())
147    }
148
149    /// Return this byte slice as a `&mut BStr`.
150    ///
151    /// `&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    fn as_bstr_mut(&mut self) -> &mut BStr {
169        BStr::new_mut(self.as_bytes_mut())
170    }
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    fn from_os_str(os_str: &OsStr) -> Option<&[u8]> {
197        #[cfg(unix)]
198        #[inline]
199        fn imp(os_str: &OsStr) -> Option<&[u8]> {
200            use std::os::unix::ffi::OsStrExt;
201
202            Some(os_str.as_bytes())
203        }
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        imp(os_str)
212    }
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    fn from_path(path: &Path) -> Option<&[u8]> {
239        Self::from_os_str(path.as_os_str())
240    }
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    fn to_str(&self) -> Result<&str, Utf8Error> {
274        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    }
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    unsafe fn to_str_unchecked(&self) -> &str {
309        str::from_utf8_unchecked(self.as_bytes())
310    }
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    fn to_str_lossy(&self) -> Cow<'_, str> {
374        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                    Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes()))
380                }
381            }
382            Err(err) => {
383                let mut lossy = String::with_capacity(self.as_bytes().len());
384                let (valid, after) =
385                    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                lossy.push_str(unsafe { str::from_utf8_unchecked(valid) });
389                lossy.push_str("\u{FFFD}");
390                if let Some(len) = err.error_len() {
391                    after[len..].to_str_lossy_into(&mut lossy);
392                }
393                Cow::Owned(lossy)
394            }
395        }
396    }
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    fn to_str_lossy_into(&self, dest: &mut String) {
431        let mut bytes = self.as_bytes();
432        dest.reserve(bytes.len());
433        loop {
434            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                    dest.push_str(unsafe { str::from_utf8_unchecked(bytes) });
439                    break;
440                }
441                Err(err) => {
442                    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                    dest.push_str(unsafe { str::from_utf8_unchecked(valid) });
446                    dest.push_str("\u{FFFD}");
447                    match err.error_len() {
448                        None => break,
449                        Some(len) => bytes = &after[len..],
450                    }
451                }
452            }
453        }
454    }
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    fn to_os_str(&self) -> Result<&OsStr, Utf8Error> {
481        #[cfg(unix)]
482        #[inline]
483        fn imp(bytes: &[u8]) -> Result<&OsStr, Utf8Error> {
484            use std::os::unix::ffi::OsStrExt;
485
486            Ok(OsStr::from_bytes(bytes))
487        }
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        imp(self.as_bytes())
496    }
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    fn to_os_str_lossy(&self) -> Cow<'_, OsStr> {
521        #[cfg(unix)]
522        #[inline]
523        fn imp(bytes: &[u8]) -> Cow<'_, OsStr> {
524            use std::os::unix::ffi::OsStrExt;
525
526            Cow::Borrowed(OsStr::from_bytes(bytes))
527        }
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        imp(self.as_bytes())
541    }
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    fn to_path(&self) -> Result<&Path, Utf8Error> {
568        self.to_os_str().map(Path::new)
569    }
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    fn to_path_lossy(&self) -> Cow<'_, Path> {
595        use std::path::PathBuf;
596
597        match self.to_os_str_lossy() {
598            Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)),
599            Cow::Owned(x) => Cow::Owned(PathBuf::from(x)),
600        }
601    }
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    fn repeatn(&self, n: usize) -> Vec<u8> {
623        self.as_bytes().repeat(n)
624    }
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    fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool {
641        self.find(needle).is_some()
642    }
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    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
659        self.as_bytes().starts_with(prefix.as_ref())
660    }
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    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
677        self.as_bytes().ends_with(suffix.as_ref())
678    }
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    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
712        Finder::new(needle.as_ref()).find(self.as_bytes())
713    }
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    fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
749        FinderReverse::new(needle.as_ref()).rfind(self.as_bytes())
750    }
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    fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
791        &'h self,
792        needle: &'n B,
793    ) -> Find<'h, 'n> {
794        Find::new(self.as_bytes(), needle.as_ref())
795    }
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    fn rfind_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
836        &'h self,
837        needle: &'n B,
838    ) -> FindReverse<'h, 'n> {
839        FindReverse::new(self.as_bytes(), needle.as_ref())
840    }
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    fn find_byte(&self, byte: u8) -> Option<usize> {
857        memchr(byte, self.as_bytes())
858    }
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    fn rfind_byte(&self, byte: u8) -> Option<usize> {
875        memrchr(byte, self.as_bytes())
876    }
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    fn find_char(&self, ch: char) -> Option<usize> {
899        self.find(ch.encode_utf8(&mut [0; 4]))
900    }
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    fn rfind_char(&self, ch: char) -> Option<usize> {
923        self.rfind(ch.encode_utf8(&mut [0; 4]))
924    }
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    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
963        byteset::find(self.as_bytes(), byteset.as_ref())
964    }
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    fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1004        byteset::find_not(self.as_bytes(), byteset.as_ref())
1005    }
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    fn rfind_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1041        byteset::rfind(self.as_bytes(), byteset.as_ref())
1042    }
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    fn rfind_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
1078        byteset::rfind_not(self.as_bytes(), byteset.as_ref())
1079    }
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    fn fields(&self) -> Fields<'_> {
1108        Fields::new(self.as_bytes())
1109    }
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    fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F> {
1140        FieldsWith::new(self.as_bytes(), f)
1141    }
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    fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1233        &'h self,
1234        splitter: &'s B,
1235    ) -> Split<'h, 's> {
1236        Split::new(self.as_bytes(), splitter.as_ref())
1237    }
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    fn rsplit_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1327        &'h self,
1328        splitter: &'s B,
1329    ) -> SplitReverse<'h, 's> {
1330        SplitReverse::new(self.as_bytes(), splitter.as_ref())
1331    }
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    fn split_once_str<'a, B: ?Sized + AsRef<[u8]>>(
1367        &'a self,
1368        splitter: &B,
1369    ) -> Option<(&'a [u8], &'a [u8])> {
1370        let bytes = self.as_bytes();
1371        let splitter = splitter.as_ref();
1372        let start = Finder::new(splitter).find(bytes)?;
1373        let end = start + splitter.len();
1374        Some((&bytes[..start], &bytes[end..]))
1375    }
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    fn rsplit_once_str<'a, B: ?Sized + AsRef<[u8]>>(
1411        &'a self,
1412        splitter: &B,
1413    ) -> Option<(&'a [u8], &'a [u8])> {
1414        let bytes = self.as_bytes();
1415        let splitter = splitter.as_ref();
1416        let start = FinderReverse::new(splitter).rfind(bytes)?;
1417        let end = start + splitter.len();
1418        Some((&bytes[..start], &bytes[end..]))
1419    }
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    fn splitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1458        &'h self,
1459        limit: usize,
1460        splitter: &'s B,
1461    ) -> SplitN<'h, 's> {
1462        SplitN::new(self.as_bytes(), splitter.as_ref(), limit)
1463    }
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    fn rsplitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
1504        &'h self,
1505        limit: usize,
1506        splitter: &'s B,
1507    ) -> SplitNReverse<'h, 's> {
1508        SplitNReverse::new(self.as_bytes(), splitter.as_ref(), limit)
1509    }
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    fn replace<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1549        &self,
1550        needle: N,
1551        replacement: R,
1552    ) -> Vec<u8> {
1553        let mut dest = Vec::with_capacity(self.as_bytes().len());
1554        self.replace_into(needle, replacement, &mut dest);
1555        dest
1556    }
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    fn replacen<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1596        &self,
1597        needle: N,
1598        replacement: R,
1599        limit: usize,
1600    ) -> Vec<u8> {
1601        let mut dest = Vec::with_capacity(self.as_bytes().len());
1602        self.replacen_into(needle, replacement, limit, &mut dest);
1603        dest
1604    }
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    fn replace_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1654        &self,
1655        needle: N,
1656        replacement: R,
1657        dest: &mut Vec<u8>,
1658    ) {
1659        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
1660
1661        let mut last = 0;
1662        for start in self.find_iter(needle) {
1663            dest.push_str(&self.as_bytes()[last..start]);
1664            dest.push_str(replacement);
1665            last = start + needle.len();
1666        }
1667        dest.push_str(&self.as_bytes()[last..]);
1668    }
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    fn replacen_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
1718        &self,
1719        needle: N,
1720        replacement: R,
1721        limit: usize,
1722        dest: &mut Vec<u8>,
1723    ) {
1724        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
1725
1726        let mut last = 0;
1727        for start in self.find_iter(needle).take(limit) {
1728            dest.push_str(&self.as_bytes()[last..start]);
1729            dest.push_str(replacement);
1730            last = start + needle.len();
1731        }
1732        dest.push_str(&self.as_bytes()[last..]);
1733    }
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    fn bytes(&self) -> Bytes<'_> {
1750        Bytes { it: self.as_bytes().iter() }
1751    }
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    fn chars(&self) -> Chars<'_> {
1780        Chars::new(self.as_bytes())
1781    }
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    fn char_indices(&self) -> CharIndices<'_> {
1835        CharIndices::new(self.as_bytes())
1836    }
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    fn utf8_chunks(&self) -> Utf8Chunks<'_> {
1872        Utf8Chunks { bytes: self.as_bytes() }
1873    }
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    fn graphemes(&self) -> Graphemes<'_> {
1904        Graphemes::new(self.as_bytes())
1905    }
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    fn grapheme_indices(&self) -> GraphemeIndices<'_> {
1950        GraphemeIndices::new(self.as_bytes())
1951    }
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    fn words(&self) -> Words<'_> {
1986        Words::new(self.as_bytes())
1987    }
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    fn word_indices(&self) -> WordIndices<'_> {
2024        WordIndices::new(self.as_bytes())
2025    }
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    fn words_with_breaks(&self) -> WordsWithBreaks<'_> {
2054        WordsWithBreaks::new(self.as_bytes())
2055    }
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    fn words_with_break_indices(&self) -> WordsWithBreakIndices<'_> {
2091        WordsWithBreakIndices::new(self.as_bytes())
2092    }
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    fn sentences(&self) -> Sentences<'_> {
2123        Sentences::new(self.as_bytes())
2124    }
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    fn sentence_indices(&self) -> SentenceIndices<'_> {
2157        SentenceIndices::new(self.as_bytes())
2158    }
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    fn lines(&self) -> Lines<'_> {
2188        Lines::new(self.as_bytes())
2189    }
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    fn lines_with_terminator(&self) -> LinesWithTerminator<'_> {
2232        LinesWithTerminator::new(self.as_bytes())
2233    }
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    fn trim(&self) -> &[u8] {
2254        self.trim_start().trim_end()
2255    }
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    fn trim_start(&self) -> &[u8] {
2275        let start = whitespace_len_fwd(self.as_bytes());
2276        &self.as_bytes()[start..]
2277    }
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    fn trim_end(&self) -> &[u8] {
2297        let end = whitespace_len_rev(self.as_bytes());
2298        &self.as_bytes()[..end]
2299    }
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    fn trim_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2316        self.trim_start_with(&mut trim).trim_end_with(&mut trim)
2317    }
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    fn trim_start_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2334        for (s, _, ch) in self.char_indices() {
2335            if !trim(ch) {
2336                return &self.as_bytes()[s..];
2337            }
2338        }
2339        b""
2340    }
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    fn trim_end_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
2357        for (_, e, ch) in self.char_indices().rev() {
2358            if !trim(ch) {
2359                return &self.as_bytes()[..e];
2360            }
2361        }
2362        b""
2363    }
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    fn to_lowercase(&self) -> Vec<u8> {
2413        let mut buf = vec![];
2414        self.to_lowercase_into(&mut buf);
2415        buf
2416    }
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    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        buf.reserve(self.as_bytes().len());
2483        for (s, e, ch) in self.char_indices() {
2484            if ch == '\u{FFFD}' {
2485                buf.push_str(&self.as_bytes()[s..e]);
2486            } else if ch.is_ascii() {
2487                buf.push_char(ch.to_ascii_lowercase());
2488            } else {
2489                for upper in ch.to_lowercase() {
2490                    buf.push_char(upper);
2491                }
2492            }
2493        }
2494    }
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    fn to_ascii_lowercase(&self) -> Vec<u8> {
2530        self.as_bytes().to_ascii_lowercase()
2531    }
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    fn make_ascii_lowercase(&mut self) {
2567        self.as_bytes_mut().make_ascii_lowercase();
2568    }
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    fn to_uppercase(&self) -> Vec<u8> {
2618        let mut buf = vec![];
2619        self.to_uppercase_into(&mut buf);
2620        buf
2621    }
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    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        buf.reserve(self.as_bytes().len());
2685        for (s, e, ch) in self.char_indices() {
2686            if ch == '\u{FFFD}' {
2687                buf.push_str(&self.as_bytes()[s..e]);
2688            } else if ch.is_ascii() {
2689                buf.push_char(ch.to_ascii_uppercase());
2690            } else {
2691                for upper in ch.to_uppercase() {
2692                    buf.push_char(upper);
2693                }
2694            }
2695        }
2696    }
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    fn to_ascii_uppercase(&self) -> Vec<u8> {
2732        self.as_bytes().to_ascii_uppercase()
2733    }
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    fn make_ascii_uppercase(&mut self) {
2769        self.as_bytes_mut().make_ascii_uppercase();
2770    }
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    fn escape_bytes(&self) -> EscapeBytes<'_> {
2810        EscapeBytes::new(self.as_bytes())
2811    }
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    fn reverse_bytes(&mut self) {
2837        self.as_bytes_mut().reverse();
2838    }
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    fn reverse_chars(&mut self) {
2908        let mut i = 0;
2909        loop {
2910            let (_, size) = utf8::decode(&self.as_bytes()[i..]);
2911            if size == 0 {
2912                break;
2913            }
2914            if size > 1 {
2915                self.as_bytes_mut()[i..i + size].reverse_bytes();
2916            }
2917            i += size;
2918        }
2919        self.reverse_bytes();
2920    }
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    fn reverse_graphemes(&mut self) {
2966        use crate::unicode::decode_grapheme;
2967
2968        let mut i = 0;
2969        loop {
2970            let (_, size) = decode_grapheme(&self.as_bytes()[i..]);
2971            if size == 0 {
2972                break;
2973            }
2974            if size > 1 {
2975                self.as_bytes_mut()[i..i + size].reverse_bytes();
2976            }
2977            i += size;
2978        }
2979        self.reverse_bytes();
2980    }
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    fn is_ascii(&self) -> bool {
3001        ascii::first_non_ascii_byte(self.as_bytes()) == self.as_bytes().len()
3002    }
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    fn is_utf8(&self) -> bool {
3029        utf8::validate(self.as_bytes()).is_ok()
3030    }
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    fn last_byte(&self) -> Option<u8> {
3050        let bytes = self.as_bytes();
3051        bytes.last().copied()
3052    }
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    fn find_non_ascii_byte(&self) -> Option<usize> {
3071        let index = ascii::first_non_ascii_byte(self.as_bytes());
3072        if index == self.as_bytes().len() {
3073            None
3074        } else {
3075            Some(index)
3076        }
3077    }
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)]
3097pub struct Finder<'a>(memmem::Finder<'a>);
3098
3099impl<'a> Finder<'a> {
3100    /// Create a new finder for the given needle.
3101    #[inline]
3102    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
3103        Finder(memmem::Finder::new(needle.as_ref()))
3104    }
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    pub fn into_owned(self) -> Finder<'static> {
3116        Finder(self.0.into_owned())
3117    }
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    pub fn needle(&self) -> &[u8] {
3127        self.0.needle()
3128    }
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    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3159        self.0.find(haystack.as_ref())
3160    }
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)]
3180pub struct FinderReverse<'a>(memmem::FinderRev<'a>);
3181
3182impl<'a> FinderReverse<'a> {
3183    /// Create a new reverse finder for the given needle.
3184    #[inline]
3185    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a> {
3186        FinderReverse(memmem::FinderRev::new(needle.as_ref()))
3187    }
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    pub fn into_owned(self) -> FinderReverse<'static> {
3199        FinderReverse(self.0.into_owned())
3200    }
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    pub fn needle(&self) -> &[u8] {
3210        self.0.needle()
3211    }
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    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
3242        self.0.rfind(haystack.as_ref())
3243    }
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)]
3253pub struct Find<'h, 'n> {
3254    it: memmem::FindIter<'h, 'n>,
3255    haystack: &'h [u8],
3256    needle: &'n [u8],
3257}
3258
3259impl<'h, 'n> Find<'h, 'n> {
3260    fn new(haystack: &'h [u8], needle: &'n [u8]) -> Find<'h, 'n> {
3261        Find { it: memmem::find_iter(haystack, needle), haystack, needle }
3262    }
3263}
3264
3265impl<'h, 'n> Iterator for Find<'h, 'n> {
3266    type Item = usize;
3267
3268    #[inline]
3269    fn next(&mut self) -> Option<usize> {
3270        self.it.next()
3271    }
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)]
3281pub struct FindReverse<'h, 'n> {
3282    it: memmem::FindRevIter<'h, 'n>,
3283    haystack: &'h [u8],
3284    needle: &'n [u8],
3285}
3286
3287impl<'h, 'n> FindReverse<'h, 'n> {
3288    fn new(haystack: &'h [u8], needle: &'n [u8]) -> FindReverse<'h, 'n> {
3289        FindReverse {
3290            it: memmem::rfind_iter(haystack, needle),
3291            haystack,
3292            needle,
3293        }
3294    }
3295
3296    fn haystack(&self) -> &'h [u8] {
3297        self.haystack
3298    }
3299
3300    fn needle(&self) -> &'n [u8] {
3301        self.needle
3302    }
3303}
3304
3305impl<'h, 'n> Iterator for FindReverse<'h, 'n> {
3306    type Item = usize;
3307
3308    #[inline]
3309    fn next(&mut self) -> Option<usize> {
3310        self.it.next()
3311    }
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)]
3318pub struct Bytes<'a> {
3319    it: slice::Iter<'a, u8>,
3320}
3321
3322impl<'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    pub fn as_bytes(&self) -> &'a [u8] {
3328        self.it.as_slice()
3329    }
3330}
3331
3332impl<'a> Iterator for Bytes<'a> {
3333    type Item = u8;
3334
3335    #[inline]
3336    fn next(&mut self) -> Option<u8> {
3337        self.it.next().copied()
3338    }
3339
3340    #[inline]
3341    fn size_hint(&self) -> (usize, Option<usize>) {
3342        self.it.size_hint()
3343    }
3344}
3345
3346impl<'a> DoubleEndedIterator for Bytes<'a> {
3347    #[inline]
3348    fn next_back(&mut self) -> Option<u8> {
3349        self.it.next_back().copied()
3350    }
3351}
3352
3353impl<'a> ExactSizeIterator for Bytes<'a> {
3354    #[inline]
3355    fn len(&self) -> usize {
3356        self.it.len()
3357    }
3358}
3359
3360impl<'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)]
3374pub struct Fields<'a> {
3375    it: FieldsWith<'a, fn(char) -> bool>,
3376}
3377
3378#[cfg(feature = "unicode")]
3379impl<'a> Fields<'a> {
3380    fn new(bytes: &'a [u8]) -> Fields<'a> {
3381        Fields { it: bytes.fields_with(char::is_whitespace) }
3382    }
3383}
3384
3385#[cfg(feature = "unicode")]
3386impl<'a> Iterator for Fields<'a> {
3387    type Item = &'a [u8];
3388
3389    #[inline]
3390    fn next(&mut self) -> Option<&'a [u8]> {
3391        self.it.next()
3392    }
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)]
3405pub struct FieldsWith<'a, F> {
3406    f: F,
3407    bytes: &'a [u8],
3408    chars: CharIndices<'a>,
3409}
3410
3411impl<'a, F: FnMut(char) -> bool> FieldsWith<'a, F> {
3412    fn new(bytes: &'a [u8], f: F) -> FieldsWith<'a, F> {
3413        FieldsWith { f, bytes, chars: bytes.char_indices() }
3414    }
3415}
3416
3417impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F> {
3418    type Item = &'a [u8];
3419
3420    #[inline]
3421    fn next(&mut self) -> Option<&'a [u8]> {
3422        let (start, mut end);
3423        loop {
3424            match self.chars.next() {
3425                None => return None,
3426                Some((s, e, ch)) => {
3427                    if !(self.f)(ch) {
3428                        start = s;
3429                        end = e;
3430                        break;
3431                    }
3432                }
3433            }
3434        }
3435        for (_, e, ch) in self.chars.by_ref() {
3436            if (self.f)(ch) {
3437                break;
3438            }
3439            end = e;
3440        }
3441        Some(&self.bytes[start..end])
3442    }
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)]
3450pub 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
3462impl<'h, 's> Split<'h, 's> {
3463    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> Split<'h, 's> {
3464        let finder = haystack.find_iter(splitter);
3465        Split { finder, last: 0, done: false }
3466    }
3467}
3468
3469impl<'h, 's> Iterator for Split<'h, 's> {
3470    type Item = &'h [u8];
3471
3472    #[inline]
3473    fn next(&mut self) -> Option<&'h [u8]> {
3474        let haystack = self.finder.haystack;
3475        match self.finder.next() {
3476            Some(start) => {
3477                let next = &haystack[self.last..start];
3478                self.last = start + self.finder.needle.len();
3479                Some(next)
3480            }
3481            None => {
3482                if self.last >= haystack.len() {
3483                    if !self.done {
3484                        self.done = true;
3485                        Some(b"")
3486                    } else {
3487                        None
3488                    }
3489                } else {
3490                    let s = &haystack[self.last..];
3491                    self.last = haystack.len();
3492                    self.done = true;
3493                    Some(s)
3494                }
3495            }
3496        }
3497    }
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)]
3506pub 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
3518impl<'h, 's> SplitReverse<'h, 's> {
3519    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> SplitReverse<'h, 's> {
3520        let finder = haystack.rfind_iter(splitter);
3521        SplitReverse { finder, last: haystack.len(), done: false }
3522    }
3523}
3524
3525impl<'h, 's> Iterator for SplitReverse<'h, 's> {
3526    type Item = &'h [u8];
3527
3528    #[inline]
3529    fn next(&mut self) -> Option<&'h [u8]> {
3530        let haystack = self.finder.haystack();
3531        match self.finder.next() {
3532            Some(start) => {
3533                let nlen = self.finder.needle().len();
3534                let next = &haystack[start + nlen..self.last];
3535                self.last = start;
3536                Some(next)
3537            }
3538            None => {
3539                if self.last == 0 {
3540                    if !self.done {
3541                        self.done = true;
3542                        Some(b"")
3543                    } else {
3544                        None
3545                    }
3546                } else {
3547                    let s = &haystack[..self.last];
3548                    self.last = 0;
3549                    self.done = true;
3550                    Some(s)
3551                }
3552            }
3553        }
3554    }
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)]
3563pub struct SplitN<'h, 's> {
3564    split: Split<'h, 's>,
3565    limit: usize,
3566    count: usize,
3567}
3568
3569impl<'h, 's> SplitN<'h, 's> {
3570    fn new(
3571        haystack: &'h [u8],
3572        splitter: &'s [u8],
3573        limit: usize,
3574    ) -> SplitN<'h, 's> {
3575        let split = haystack.split_str(splitter);
3576        SplitN { split, limit, count: 0 }
3577    }
3578}
3579
3580impl<'h, 's> Iterator for SplitN<'h, 's> {
3581    type Item = &'h [u8];
3582
3583    #[inline]
3584    fn next(&mut self) -> Option<&'h [u8]> {
3585        self.count += 1;
3586        if self.count > self.limit || self.split.done {
3587            None
3588        } else if self.count == self.limit {
3589            Some(&self.split.finder.haystack[self.split.last..])
3590        } else {
3591            self.split.next()
3592        }
3593    }
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)]
3602pub struct SplitNReverse<'h, 's> {
3603    split: SplitReverse<'h, 's>,
3604    limit: usize,
3605    count: usize,
3606}
3607
3608impl<'h, 's> SplitNReverse<'h, 's> {
3609    fn new(
3610        haystack: &'h [u8],
3611        splitter: &'s [u8],
3612        limit: usize,
3613    ) -> SplitNReverse<'h, 's> {
3614        let split = haystack.rsplit_str(splitter);
3615        SplitNReverse { split, limit, count: 0 }
3616    }
3617}
3618
3619impl<'h, 's> Iterator for SplitNReverse<'h, 's> {
3620    type Item = &'h [u8];
3621
3622    #[inline]
3623    fn next(&mut self) -> Option<&'h [u8]> {
3624        self.count += 1;
3625        if self.count > self.limit || self.split.done {
3626            None
3627        } else if self.count == self.limit {
3628            Some(&self.split.finder.haystack()[..self.split.last])
3629        } else {
3630            self.split.next()
3631        }
3632    }
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)]
3642pub struct Lines<'a> {
3643    it: LinesWithTerminator<'a>,
3644}
3645
3646impl<'a> Lines<'a> {
3647    fn new(bytes: &'a [u8]) -> Lines<'a> {
3648        Lines { it: LinesWithTerminator::new(bytes) }
3649    }
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    pub fn as_bytes(&self) -> &'a [u8] {
3670        self.it.bytes
3671    }
3672}
3673
3674impl<'a> Iterator for Lines<'a> {
3675    type Item = &'a [u8];
3676
3677    #[inline]
3678    fn next(&mut self) -> Option<&'a [u8]> {
3679        Some(trim_last_terminator(self.it.next()?))
3680    }
3681}
3682
3683impl<'a> DoubleEndedIterator for Lines<'a> {
3684    #[inline]
3685    fn next_back(&mut self) -> Option<Self::Item> {
3686        Some(trim_last_terminator(self.it.next_back()?))
3687    }
3688}
3689
3690impl<'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)]
3706pub struct LinesWithTerminator<'a> {
3707    bytes: &'a [u8],
3708}
3709
3710impl<'a> LinesWithTerminator<'a> {
3711    fn new(bytes: &'a [u8]) -> LinesWithTerminator<'a> {
3712        LinesWithTerminator { bytes }
3713    }
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    pub fn as_bytes(&self) -> &'a [u8] {
3734        self.bytes
3735    }
3736}
3737
3738impl<'a> Iterator for LinesWithTerminator<'a> {
3739    type Item = &'a [u8];
3740
3741    #[inline]
3742    fn next(&mut self) -> Option<&'a [u8]> {
3743        match self.bytes.find_byte(b'\n') {
3744            None if self.bytes.is_empty() => None,
3745            None => {
3746                let line = self.bytes;
3747                self.bytes = b"";
3748                Some(line)
3749            }
3750            Some(end) => {
3751                let line = &self.bytes[..=end];
3752                self.bytes = &self.bytes[end + 1..];
3753                Some(line)
3754            }
3755        }
3756    }
3757}
3758
3759impl<'a> DoubleEndedIterator for LinesWithTerminator<'a> {
3760    #[inline]
3761    fn next_back(&mut self) -> Option<Self::Item> {
3762        let end = self.bytes.len().checked_sub(1)?;
3763        match self.bytes[..end].rfind_byte(b'\n') {
3764            None => {
3765                let line = self.bytes;
3766                self.bytes = b"";
3767                Some(line)
3768            }
3769            Some(end) => {
3770                let line = &self.bytes[end + 1..];
3771                self.bytes = &self.bytes[..=end];
3772                Some(line)
3773            }
3774        }
3775    }
3776}
3777
3778impl<'a> iter::FusedIterator for LinesWithTerminator<'a> {}
3779
3780fn trim_last_terminator(mut s: &[u8]) -> &[u8] {
3781    if s.last_byte() == Some(b'\n') {
3782        s = &s[..s.len() - 1];
3783        if s.last_byte() == Some(b'\r') {
3784            s = &s[..s.len() - 1];
3785        }
3786    }
3787    s
3788}
3789
3790#[cfg(all(test, feature = "std"))]
3791mod 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}