#![allow(dead_code)]
use super::constants::PAGE_SIZE;
pub trait ListNavigator {
fn selected(&self) -> usize;
fn set_selected(&mut self, index: usize);
fn max_index(&self) -> usize;
fn move_up(&mut self, count: usize) {
let current = self.selected();
self.set_selected(current.saturating_sub(count));
}
fn move_down(&mut self, count: usize) {
let current = self.selected();
let max = self.max_index();
self.set_selected((current + count).min(max));
}
fn page_up(&mut self) {
self.move_up(PAGE_SIZE);
}
fn page_down(&mut self) {
self.move_down(PAGE_SIZE);
}
fn jump_to_top(&mut self) {
self.set_selected(0);
}
fn jump_to_bottom(&mut self) {
self.set_selected(self.max_index());
}
}
#[derive(Debug, Clone, Default)]
pub struct SimpleListNav {
selected: usize,
count: usize,
}
impl SimpleListNav {
pub fn new(count: usize) -> Self {
Self { selected: 0, count }
}
pub fn set_count(&mut self, count: usize) {
self.count = count;
if self.selected > self.max_index() {
self.selected = self.max_index();
}
}
pub fn count(&self) -> usize {
self.count
}
}
impl ListNavigator for SimpleListNav {
fn selected(&self) -> usize {
self.selected
}
fn set_selected(&mut self, index: usize) {
self.selected = index.min(self.max_index());
}
fn max_index(&self) -> usize {
self.count.saturating_sub(1)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_list_nav() {
let mut nav = SimpleListNav::new(10);
assert_eq!(nav.selected(), 0);
assert_eq!(nav.max_index(), 9);
nav.move_down(3);
assert_eq!(nav.selected(), 3);
nav.move_up(1);
assert_eq!(nav.selected(), 2);
nav.jump_to_bottom();
assert_eq!(nav.selected(), 9);
nav.jump_to_top();
assert_eq!(nav.selected(), 0);
}
#[test]
fn test_list_nav_bounds() {
let mut nav = SimpleListNav::new(5);
nav.move_up(10);
assert_eq!(nav.selected(), 0);
nav.move_down(100);
assert_eq!(nav.selected(), 4);
}
#[test]
fn test_list_nav_empty() {
let mut nav = SimpleListNav::new(0);
assert_eq!(nav.max_index(), 0);
nav.move_down(1);
assert_eq!(nav.selected(), 0);
}
}