Skip to main content

subtr_actor/
search.rs

1use serde::Serialize;
2
3/// Enum to define the direction of searching within a collection.
4#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
5pub enum SearchDirection {
6    Forward,
7    Backward,
8}
9
10/// Searches for an item in a slice in a specified direction and returns the
11/// first item that matches the provided predicate.
12///
13/// # Arguments
14///
15/// * `items` - The list of items to search.
16/// * `current_index` - The index to start the search from.
17/// * `direction` - The direction to search in.
18/// * `predicate` - A function that takes an item and returns an [`Option<R>`].
19///   When this function returns `Some(R)`, the item is considered a match.
20///
21/// # Returns
22///
23/// Returns a tuple of the index and the result `R` of the predicate for the first item that matches.
24pub fn find_in_direction<T, F, R>(
25    items: &[T],
26    current_index: usize,
27    direction: SearchDirection,
28    predicate: F,
29) -> Option<(usize, R)>
30where
31    F: Fn(&T) -> Option<R>,
32{
33    match direction {
34        SearchDirection::Forward => items
35            .iter()
36            .enumerate()
37            .skip(current_index + 1)
38            .find_map(|(i, item)| predicate(item).map(|res| (i, res))),
39        SearchDirection::Backward => items[..current_index]
40            .iter()
41            .enumerate()
42            .rev()
43            .find_map(|(i, item)| predicate(item).map(|res| (i, res))),
44    }
45}