pub fn relative_find<T, F>(
    list: &[T],
    reference_finder: F,
    shift: i32,
    should_loop: bool,
) -> Option<&T>
where
    F: Fn(&T) -> bool,
{
    let len = list.len() as i32;
    let reference_index = list.iter().position(reference_finder)?;
    let loops = if shift.is_negative() {
        // check if shift is larger than there are elements on the left
        shift.unsigned_abs() as usize > reference_index
    } else {
        // check if shift is larger than there are elements on the right
        shift as usize > len as usize - (reference_index + 1)
    };

    let relative_index = if loops && !should_loop {
        None
    } else {
        let shift = shift % len;
        let shifted_index = reference_index as i32 + shift;
        let max_index = len - 1;
        if shifted_index < 0 {
            Some((len + shifted_index) as usize)
        } else if shifted_index > max_index {
            Some((shifted_index - len) as usize)
        } else {
            Some(shifted_index as usize)
        }
    }?;

    list.get(relative_index)
}
Find element relative to reference element.

eg. to get the next element, use `shift` 1,
to get the previous element, use `shift` -1.

## Arguments
* `list` - The list to get the element from
* `reference_finder` - Predicate to find the reference element in the list
* `shift` - The shift (distance) of the element you try to find relative to the reference element, can be negative to move left
* `should_loop` - If the list should loop when the `shift` goes beyond the start/end of the list

## Example
```
let list = vec!["hello", "world", "foo", "bar"];
let result = leftwm_core::utils::helpers::relative_find(&list, |&e| e == "world", 2, false);
assert_eq!(result, Some(&"bar"));
```
leftwm-core/src/utils/helpers.rs