Skip to main content

elephantry_extras/
pager.rs

1#[derive(Clone, Debug, Eq, PartialEq)]
2#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
3pub struct Pager {
4    pub count: usize,
5    pub page: usize,
6    pub max_per_page: usize,
7}
8
9impl Pager {
10    pub(crate) fn last_page(&self) -> usize {
11        (self.count as f32 / self.max_per_page as f32).ceil() as usize
12    }
13
14    pub(crate) fn not_needed(&self) -> bool {
15        self.last_page() <= 1
16    }
17}
18
19#[derive(Debug, Default)]
20pub struct Config {
21    pub base_url: String,
22    pub page_param: String,
23    pub limit_param: String,
24    pub ellipsis: usize,
25}
26
27#[derive(Debug, PartialEq, Eq)]
28pub(crate) struct Bounds {
29    pub start: usize,
30    pub end: usize,
31}
32
33impl Bounds {
34    pub fn new(pager: &Pager, config: &Config) -> Self {
35        let last_page = pager.last_page();
36
37        let (start, end) = if pager.page <= config.ellipsis {
38            (1, (config.ellipsis + 1).min(last_page))
39        } else if pager.page >= last_page - config.ellipsis {
40            ((last_page - config.ellipsis).max(1), last_page)
41        } else {
42            let half = (config.ellipsis - 1) / 2;
43            (pager.page - half, pager.page + half)
44        };
45
46        Self { start, end }
47    }
48}
49
50#[cfg(test)]
51mod test {
52    #[test]
53    fn bounds() {
54        let pager = crate::Pager {
55            count: 237,
56            page: 10,
57            max_per_page: 25,
58        };
59        let config = crate::pager::Config {
60            ellipsis: 9,
61
62            ..Default::default()
63        };
64        let bounds = crate::pager::Bounds::new(&pager, &config);
65
66        assert_eq!(bounds, crate::pager::Bounds { start: 1, end: 10 });
67    }
68}