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}