pagino/
lib.rs

1const FIRST: i32 = -1;
2const PREVIOUS: i32 = -2;
3const START_ELLIPSIS: i32 = -3;
4const END_ELLIPSIS: i32 = -4;
5const NEXT: i32 = -5;
6const LAST: i32 = -6;
7
8pub struct Pagino {
9  pub show_first: bool,
10  pub show_previous: bool,
11  pub show_next: bool,
12  pub show_last: bool,
13  pub page: i32,
14  pub count: i32,
15  pub sibling_count: i32,
16  pub boundary_count: i32,
17}
18
19impl Pagino {
20  pub fn new(
21    show_first: bool,
22    show_previous: bool,
23    show_next: bool,
24    show_last: bool,
25    page: i32,
26    count: i32,
27    sibling_count: i32,
28    boundary_count: i32,
29  ) -> Pagino {
30    Pagino {
31      show_first,
32      show_previous,
33      show_next,
34      show_last,
35      page,
36      count,
37      sibling_count,
38      boundary_count,
39    }
40  }
41
42  pub fn set_count(&mut self, count: i32) -> () {
43    self.count = count;
44  }
45
46  pub fn set_page(&mut self, page: i32) -> () {
47    if page > 0 && page <= self.count {
48      self.page = page;
49    }
50  }
51
52  pub fn first(&mut self) -> () {
53    self.set_page(1)
54  }
55
56  pub fn last(&mut self) -> () {
57    self.set_page(self.count)
58  }
59
60  pub fn next(&mut self) -> () {
61    self.set_page(self.page + 1)
62  }
63
64  pub fn previous(&mut self) -> () {
65    self.set_page(self.page - 1)
66  }
67
68  pub fn get_pages(&self) -> Vec<i32> {
69    let start_pages: Vec<i32> = create_start_pages(self.boundary_count, self.count);
70    let end_pages: Vec<i32> = create_end_pages(self.boundary_count, self.count);
71
72    let sibling_start: i32 = create_siblings_start(
73      self.boundary_count,
74      self.count,
75      self.page,
76      self.sibling_count,
77    );
78
79    let sibling_end: i32 = create_siblings_end(
80      self.boundary_count,
81      self.count,
82      self.page,
83      self.sibling_count,
84      &end_pages,
85    );
86
87    let mut pages: Vec<i32> = Vec::new();
88
89    if self.show_first {
90      pages.push(FIRST);
91    }
92
93    if self.show_previous {
94      pages.push(PREVIOUS);
95    }
96
97    for x in start_pages {
98      pages.push(x);
99    }
100
101    println!(
102      "sibling_start {} boundary_count {}",
103      sibling_start,
104      self.boundary_count + 2
105    );
106    if sibling_start > self.boundary_count + 2 {
107      pages.push(START_ELLIPSIS);
108    } else if self.boundary_count + 1 < self.count - self.boundary_count {
109      pages.push(self.boundary_count + 1)
110    }
111
112    for x in create_range(sibling_start, sibling_end) {
113      pages.push(x);
114    }
115
116    if sibling_end < self.count - self.boundary_count - 1 {
117      pages.push(END_ELLIPSIS);
118    } else if self.count - self.boundary_count > self.boundary_count {
119      pages.push(self.count - self.boundary_count);
120    }
121
122    for x in end_pages {
123      pages.push(x);
124    }
125
126    if self.show_next {
127      pages.push(NEXT);
128    }
129
130    if self.show_last {
131      pages.push(LAST);
132    }
133
134    pages
135  }
136}
137
138fn min(a: i32, b: i32) -> i32 {
139  if a < b {
140    a
141  } else {
142    b
143  }
144}
145
146fn max(a: i32, b: i32) -> i32 {
147  if a > b {
148    a
149  } else {
150    b
151  }
152}
153
154fn create_range(start: i32, end: i32) -> Vec<i32> {
155  let length: i32 = end - start + 1;
156  let mut vec: Vec<i32> = Vec::new();
157  let mut count = 0;
158  while count < length {
159    vec.push(start + count);
160    count += 1;
161  }
162
163  vec
164}
165
166fn create_start_pages(boundary_count: i32, count: i32) -> Vec<i32> {
167  create_range(1, min(boundary_count, count))
168}
169
170fn create_end_pages(boundary_count: i32, count: i32) -> Vec<i32> {
171  create_range(max(count - boundary_count + 1, boundary_count + 1), count)
172}
173
174fn create_siblings_start(boundary_count: i32, count: i32, page: i32, sibling_count: i32) -> i32 {
175  max(
176    min(
177      page - sibling_count,
178      count - boundary_count - (sibling_count * 2) - 1,
179    ),
180    boundary_count + 2,
181  )
182}
183
184fn create_siblings_end(
185  boundary_count: i32,
186  count: i32,
187  page: i32,
188  sibling_count: i32,
189  end_pages: &Vec<i32>,
190) -> i32 {
191  let end_element = if end_pages.len() > 0 {
192    end_pages[0] - 2
193  } else {
194    count - 1
195  };
196
197  min(
198    max(
199      page + sibling_count,
200      boundary_count + (sibling_count * 2) + 2,
201    ),
202    end_element,
203  )
204}