use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Display, Formatter};
pub const DEFAULT_PAGE_SIZE: u64 = 10;
pub trait IPageRequest: Send + Sync {
fn page_size(&self) -> u64;
fn page_no(&self) -> u64;
fn total(&self) -> u64;
fn do_count(&self) -> bool;
fn pages(&self) -> u64 {
if self.page_size() == 0 {
return 0;
}
let mut pages = self.total() / self.page_size();
if self.total() % self.page_size() != 0 {
pages = pages + 1;
}
return pages;
}
fn offset(&self) -> u64 {
if self.page_no() > 0 {
(self.page_no() - 1) * self.page_size()
} else {
0
}
}
fn offset_limit(&self) -> u64 {
let v = self.offset() + self.page_size();
if v > self.total() {
return self.total();
}
v
}
fn set_total(&mut self, arg: u64);
fn set_page_size(&mut self, arg: u64);
fn set_page_no(&mut self, arg: u64);
fn set_do_count(&mut self, arg: bool);
#[deprecated(note = "please use do_count()")]
fn search_count(&self) -> bool {
self.do_count()
}
#[deprecated(note = "please use set_do_count()")]
fn set_search_count(&mut self, arg: bool) {
self.set_do_count(arg)
}
}
pub trait IPage<T>: IPageRequest {
fn get_records(&self) -> &Vec<T>;
fn get_records_mut(&mut self) -> &mut Vec<T>;
fn set_records(self, arg: Vec<T>) -> Self;
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Page<T: Send + Sync> {
pub records: Vec<T>,
pub total: u64,
pub page_no: u64,
pub page_size: u64,
pub do_count: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct PageRequest {
pub total: u64,
pub page_no: u64,
pub page_size: u64,
pub do_count: bool,
}
impl PageRequest {
pub fn new(page_no: u64, page_size: u64) -> Self {
return PageRequest::new_total(page_no, page_size, DEFAULT_PAGE_SIZE);
}
pub fn new_option(page_no: Option<u64>, page_size: Option<u64>) -> Self {
return PageRequest::new(page_no.unwrap_or(1), page_size.unwrap_or(DEFAULT_PAGE_SIZE));
}
pub fn new_total(page_no: u64, page_size: u64, total: u64) -> Self {
let mut page_no = page_no;
if page_no < 1 {
page_no = 1;
}
Self {
total,
page_size,
page_no,
do_count: true,
}
}
pub fn set_total(mut self, total: u64) -> Self {
self.total = total;
self
}
pub fn set_page_size(mut self, arg: u64) -> Self {
self.page_size = arg;
self
}
pub fn set_page_no(mut self, arg: u64) -> Self {
self.page_no = arg;
self
}
pub fn set_do_count(mut self, arg: bool) -> Self {
self.do_count = arg;
self
}
}
impl Default for PageRequest {
fn default() -> Self {
return PageRequest {
total: 0,
page_size: DEFAULT_PAGE_SIZE,
page_no: 1,
do_count: true,
};
}
}
impl IPageRequest for PageRequest {
fn page_size(&self) -> u64 {
self.page_size
}
fn page_no(&self) -> u64 {
self.page_no
}
fn total(&self) -> u64 {
self.total
}
fn do_count(&self) -> bool {
self.do_count
}
fn set_total(&mut self, total: u64) {
self.total = total;
}
fn set_page_size(&mut self, arg: u64) {
self.page_size = arg;
}
fn set_page_no(&mut self, arg: u64) {
self.page_no = arg;
}
fn set_do_count(&mut self, arg: bool) {
self.do_count = arg;
}
}
impl<T: Send + Sync> Page<T> {
pub fn new(current: u64, page_size: u64) -> Self {
return Page::new_total(current, page_size, 0);
}
pub fn new_option(current: &Option<u64>, page_size: &Option<u64>) -> Self {
return Page::new(current.unwrap_or(1), page_size.unwrap_or(DEFAULT_PAGE_SIZE));
}
pub fn new_total(page_no: u64, mut page_size: u64, total: u64) -> Self {
if page_size == 0 {
page_size = DEFAULT_PAGE_SIZE;
}
if page_no < 1 {
return Self {
total,
page_size: page_size,
page_no: 1 as u64,
records: vec![],
do_count: true,
};
}
return Self {
total,
page_size,
page_no,
records: vec![],
do_count: true,
};
}
pub fn make_pages(mut data: Vec<T>, page_size: u64) -> Vec<Page<T>> {
let total = data.len() as u64;
let mut result = vec![];
let pages = PageRequest::new(1, page_size).set_total(total).pages();
for idx in 0..pages {
let mut current_page = Page::<T>::new_total(idx + 1, page_size, total as u64);
for _ in current_page.offset()..current_page.offset_limit() {
current_page.records.push(data.remove(0));
}
result.push(current_page);
}
result
}
pub fn make_ranges(total: u64, page_size: u64) -> Vec<(u64, u64)> {
let mut result = vec![];
let pages = PageRequest::new(1, page_size).set_total(total).pages();
for idx in 0..pages {
let current_page = Page::<T>::new_total(idx + 1, page_size, total);
result.push((current_page.offset(), current_page.offset_limit()));
}
result
}
pub fn set_total(mut self, total: u64) -> Self {
self.total = total;
self
}
pub fn set_page_size(mut self, arg: u64) -> Self {
self.page_size = arg;
self
}
pub fn set_page_no(mut self, arg: u64) -> Self {
self.page_no = arg;
self
}
pub fn set_do_count(mut self, arg: bool) -> Self {
self.do_count = arg;
self
}
}
impl<T: Send + Sync> Default for Page<T> {
fn default() -> Self {
return Page {
records: vec![],
total: 0,
page_size: DEFAULT_PAGE_SIZE,
page_no: 1,
do_count: true,
};
}
}
impl<T: Send + Sync> IPageRequest for Page<T> {
fn page_size(&self) -> u64 {
self.page_size
}
fn page_no(&self) -> u64 {
self.page_no
}
fn total(&self) -> u64 {
self.total
}
fn do_count(&self) -> bool {
self.do_count
}
fn set_total(&mut self, arg: u64) {
self.total = arg;
}
fn set_page_size(&mut self, arg: u64) {
self.page_size = arg;
}
fn set_page_no(&mut self, arg: u64) {
self.page_no = arg;
}
fn set_do_count(&mut self, arg: bool) {
self.do_count = arg;
}
}
impl<T: Send + Sync> IPage<T> for Page<T> {
fn get_records(&self) -> &Vec<T> {
self.records.as_ref()
}
fn get_records_mut(&mut self) -> &mut Vec<T> {
self.records.as_mut()
}
fn set_records(mut self, arg: Vec<T>) -> Self {
self.records = arg;
self
}
}
impl<T: Display + Debug + Send + Sync> Display for Page<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Page")
.field("records", &self.records)
.field("total", &self.total)
.field("page_no", &self.page_no)
.field("page_size", &self.page_size)
.field("do_count", &self.do_count)
.finish()
}
}
impl<V: Send + Sync> Page<V> {
pub fn from<T: Send + Sync>(arg: Page<T>) -> Self
where
V: From<T>,
{
let mut p = Page::<V>::new(arg.page_no, arg.page_size);
p.page_no = arg.page_no;
p.page_size = arg.page_size;
p.total = arg.total;
p.do_count = arg.do_count;
p.records = {
let mut records = Vec::with_capacity(arg.records.len());
for x in arg.records {
records.push(V::from(x));
}
records
};
p
}
}
#[cfg(test)]
mod test {
use crate::plugin::page::Page;
#[test]
fn test_page_into_range() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let ranges = Page::<i32>::make_ranges(v.len() as u64, 3);
let mut new_v = vec![];
for (offset, limit) in ranges {
for i in offset..limit {
new_v.push(i + 1);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_range_zero() {
let mut v = vec![1];
v.clear();
let ranges = Page::<i32>::make_ranges(v.len() as u64, 3);
let mut new_v = vec![];
for (offset, limit) in ranges {
for i in offset..limit {
new_v.push(i + 1);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let pages = Page::make_pages(v.clone(), 3);
assert_eq!(pages.len(), 3);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages_more_than() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let pages = Page::make_pages(v.clone(), 18);
assert_eq!(pages.len(), 1);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages_zero() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
let pages = Page::make_pages(v.clone(), 1);
assert_eq!(pages.len(), 9);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages_8() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8];
let pages = Page::make_pages(v.clone(), 3);
assert_eq!(pages.len(), 3);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages_10() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let pages = Page::make_pages(v.clone(), 3);
assert_eq!(pages.len(), 4);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
#[test]
fn test_page_into_pages_one() {
let v = vec![1];
let pages = Page::make_pages(v.clone(), 1);
let mut new_v = vec![];
for x in pages {
for i in x.records {
new_v.push(i);
}
}
assert_eq!(v, new_v);
}
}