pub fn select_next(selected: usize, max_index: usize) -> usize {
selected.saturating_add(1).min(max_index)
}
pub fn select_prev(selected: usize) -> usize {
selected.saturating_sub(1)
}
pub fn adjust_scroll(selected: usize, scroll_offset: usize, visible_count: usize) -> usize {
if visible_count == 0 {
return scroll_offset;
}
if selected < scroll_offset {
selected
} else if selected >= scroll_offset + visible_count {
selected - visible_count + 1
} else {
scroll_offset
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_select_next_basic() {
assert_eq!(select_next(0, 5), 1);
assert_eq!(select_next(4, 5), 5);
}
#[test]
fn test_select_next_at_max() {
assert_eq!(select_next(5, 5), 5);
}
#[test]
fn test_select_next_zero_max() {
assert_eq!(select_next(0, 0), 0);
}
#[test]
fn test_select_prev_basic() {
assert_eq!(select_prev(3), 2);
assert_eq!(select_prev(1), 0);
}
#[test]
fn test_select_prev_at_zero() {
assert_eq!(select_prev(0), 0);
}
#[test]
fn test_adjust_scroll_no_change_needed() {
assert_eq!(adjust_scroll(3, 0, 10), 0);
}
#[test]
fn test_adjust_scroll_selected_above_viewport() {
assert_eq!(adjust_scroll(2, 5, 10), 2);
}
#[test]
fn test_adjust_scroll_selected_below_viewport() {
assert_eq!(adjust_scroll(15, 0, 10), 6);
}
#[test]
fn test_adjust_scroll_visible_count_zero() {
assert_eq!(adjust_scroll(5, 3, 0), 3);
}
#[test]
fn test_adjust_scroll_edge_just_visible() {
assert_eq!(adjust_scroll(9, 0, 10), 0);
}
#[test]
fn test_adjust_scroll_edge_just_outside() {
assert_eq!(adjust_scroll(10, 0, 10), 1);
}
}