slice_find/
simple.rs

1pub fn slice_find<T: PartialEq>(haystack: &[T], needle: &[T]) -> Option<usize> {
2    let haystack_len = haystack.len();
3    let needle_len = needle.len();
4
5    // Quick edge cases
6    if needle_len == 0 {
7        return Some(0); // Empty pattern matches at the start
8    }
9    if needle_len > haystack_len {
10        return None; // Pattern longer than text cannot match
11    }
12
13    if needle_len == 1 {
14        // Special case for single-element pattern
15        return haystack.iter().position(|c| { c == &needle[0] });
16    }
17    if needle_len == haystack_len {
18        // Special case for length equal
19        if haystack == needle {
20            return Some(0);
21        } else {
22            return None;
23        }
24    }
25
26    // The pre-check is a preliminary operation that determines the existence of each item in the needle within the haystack. It is agnostic to the order or contiguity of the items, as if one of needle's item is absent in haystack, it is impossible to match. Consequently, the pre-check saves computational resources by returning an early result.
27    /*
28    for item in needle.iter() {
29        if ! haystack.contains(item) {
30            return None;
31        }
32    }*/
33
34    let mut pos = 0;
35    while pos+needle_len <= haystack_len {
36        if haystack[pos] == needle[0] {
37            if &haystack[pos .. pos+needle_len] == needle {
38                return Some(pos);
39            }
40        }
41
42        pos += 1;
43    }
44
45    None
46}
47
48pub fn slice_contains<T: PartialEq>(haystack: &[T], needle: &[T]) -> bool {
49    slice_find(haystack, needle).is_some()
50}
51