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}