pub fn history_up_index(current: Option<usize>, len: usize) -> Option<usize> {
if len == 0 {
return None;
}
Some(match current {
None => len - 1,
Some(i) => i.saturating_sub(1),
})
}
pub fn history_down_index(current: Option<usize>, len: usize) -> Option<usize> {
match current {
Some(i) if i + 1 < len => Some(i + 1),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn up_from_none_lands_on_most_recent() {
assert_eq!(history_up_index(None, 5), Some(4));
}
#[test]
fn up_from_middle_moves_one_older() {
assert_eq!(history_up_index(Some(3), 5), Some(2));
}
#[test]
fn up_at_top_saturates_at_zero() {
assert_eq!(history_up_index(Some(0), 5), Some(0));
}
#[test]
fn up_with_empty_history_returns_none() {
assert_eq!(history_up_index(None, 0), None);
}
#[test]
fn down_from_middle_moves_one_newer() {
assert_eq!(history_down_index(Some(2), 5), Some(3));
}
#[test]
fn down_past_last_returns_none() {
assert_eq!(history_down_index(Some(4), 5), None);
}
#[test]
fn down_from_none_returns_none() {
assert_eq!(history_down_index(None, 5), None);
}
}