wutil/
slice.rs

1//! Contains extentions for rust slices.
2
3mod with_sequence_removed;
4pub use with_sequence_removed::WithSequenceRemoved;
5
6impl<T> SliceExt for [T] {
7    type Inner = T;
8
9    fn find(&self, subslice: &[T]) -> Option<usize>
10    where
11        T: PartialEq,
12    {
13        self.windows(subslice.len()).position(|w| w == subslice)
14    }
15
16    fn with_sequence_removed<'a>(&'a self, sequence: &'a [T]) -> WithSequenceRemoved<'a, T>
17    where
18        T: PartialEq,
19    {
20        WithSequenceRemoved::new(self, sequence)
21    }
22
23    fn get_slice_between(&self, slice1: &[T], slice2: &[T]) -> Option<&[T]>
24    where
25        T: PartialEq,
26    {
27        let start_idx = self.find(slice1)? + slice1.len();
28
29        let slice = self.get(start_idx..)?;
30        let end_idx = slice.find(slice2)?;
31
32        slice.get(0..end_idx)
33    }
34}
35
36pub trait SliceExt {
37    type Inner;
38
39    /// Returns the starting index of the first occurence of `subslice`.
40    fn find(&self, subslice: &Self) -> Option<usize>
41    where
42        Self::Inner: PartialEq;
43
44    /// Returns an iterator with the provided sequence filtered out once.
45    /// # Example
46    /// ```
47    /// # use wutil::prelude::*;
48    /// let Mssippi: Vec<u8> = b"Mississippi".with_sequence_removed(b"is").copied().collect();
49    /// assert_eq!(&Mssippi, b"Mssippi");
50    ///
51    /// let ab: Vec<u8> = b"aabb".with_sequence_removed(b"ab").copied().collect();
52    /// assert_eq!(&ab, b"ab");
53    ///
54    /// let a: Vec<u8> = b"aaaaa".with_sequence_removed(b"aa").copied().collect();
55    /// assert_eq!(&a, b"a");
56    /// ```
57    fn with_sequence_removed<'a>(
58        &'a self,
59        sequence: &'a [Self::Inner],
60    ) -> WithSequenceRemoved<'a, Self::Inner>
61    where
62        Self::Inner: PartialEq;
63
64    /// Gets the content between the first occurance of two subslices.
65    /// # Example
66    /// ```
67    /// # use wutil::prelude::*;
68    /// let text = b"<a>foo</a> bar 'biz'] [bax] <a>bang</a>";
69    ///
70    /// assert!(text.get_slice_between(b"<a>", b"</a>") == Some(b"foo"));
71    /// assert!(text.get_slice_between(b"'", b"'") == Some(b"biz"));
72    /// assert!(text.get_slice_between(b"[", b"]") == Some(b"bax"));
73    /// ```
74    fn get_slice_between(&self, slice1: &Self, slice2: &Self) -> Option<&Self>
75    where
76        Self::Inner: PartialEq;
77}