use ratatui::widgets::ListState;
#[derive(Debug)]
pub struct StatefulList<T> {
pub items: Vec<T>,
pub state: ListState,
}
impl<T> StatefulList<T> {
pub fn new(items: Vec<T>, mut state: ListState) -> StatefulList<T> {
state.select(Some(0));
Self { items, state }
}
pub fn with_items(items: Vec<T>) -> StatefulList<T> {
Self::new(items, ListState::default())
}
pub fn selected(&self) -> Option<&T> {
self.items.get(self.state.selected()?)
}
pub fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}
pub fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stateful_list() {
let mut list = StatefulList::with_items(vec!["data1", "data2", "data3"]);
list.state.select(Some(1));
assert_eq!(Some(&"data2"), list.selected());
list.next();
assert_eq!(Some(2), list.state.selected());
list.previous();
assert_eq!(Some(1), list.state.selected());
}
}