use vantage_expressions::traits::selectable::Selectable;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Pagination {
page: i64,
items_per_page: i64,
}
impl Pagination {
pub fn new(page: i64, items_per_page: i64) -> Self {
Self {
page: page.max(1),
items_per_page: items_per_page.max(1),
}
}
pub fn set_page(&mut self, page: i64) {
self.page = page.max(1);
}
pub fn set_ipp(&mut self, items_per_page: i64) {
let items_per_page = items_per_page.max(1);
let first_item_index = (self.page - 1) * self.items_per_page;
self.page = (first_item_index / items_per_page) + 1;
self.items_per_page = items_per_page;
}
pub fn get_page(&self) -> i64 {
self.page
}
pub fn get_ipp(&self) -> i64 {
self.items_per_page
}
pub fn limit(&self) -> i64 {
self.items_per_page
}
pub fn skip(&self) -> i64 {
(self.page - 1) * self.items_per_page
}
pub fn apply_on_select<S, E>(&self, select: &mut S)
where
S: Selectable<E>,
{
select.set_limit(Some(self.limit()), Some(self.skip()));
}
}
impl Default for Pagination {
fn default() -> Self {
Self {
page: 1,
items_per_page: 50,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_pagination() {
let p = Pagination::new(2, 25);
assert_eq!(p.get_page(), 2);
assert_eq!(p.get_ipp(), 25);
assert_eq!(p.limit(), 25);
assert_eq!(p.skip(), 25);
}
#[test]
fn test_pagination_bounds() {
let p = Pagination::new(0, 0);
assert_eq!(p.get_page(), 1);
assert_eq!(p.get_ipp(), 1);
}
#[test]
fn test_set_page() {
let mut p = Pagination::new(1, 10);
p.set_page(3);
assert_eq!(p.get_page(), 3);
assert_eq!(p.skip(), 20);
}
#[test]
fn test_set_ipp_keeps_focus() {
let mut p = Pagination::new(3, 10);
p.set_ipp(5);
assert_eq!(p.get_page(), 5);
assert_eq!(p.get_ipp(), 5);
assert_eq!(p.skip(), 20);
}
#[test]
fn test_set_ipp_larger_page_size() {
let mut p = Pagination::new(5, 5);
p.set_ipp(25);
assert_eq!(p.get_page(), 1);
assert_eq!(p.get_ipp(), 25);
assert_eq!(p.skip(), 0);
}
#[test]
fn test_default_pagination() {
let p = Pagination::default();
assert_eq!(p.get_page(), 1);
assert_eq!(p.get_ipp(), 50);
assert_eq!(p.skip(), 0);
}
}