use crate::tina::server::session::Session;
pub trait PageRequestExt {
type Target;
fn max_records(session: &Session) -> Self::Target;
fn min_records(session: &Session) -> Self::Target;
fn max_page_no(session: &Session) -> Self::Target;
fn min_page_no(session: &Session) -> Self::Target;
fn export(session: &Session) -> Self::Target;
fn with_max_records(self, session: &Session) -> Self::Target;
fn with_min_records(self, session: &Session) -> Self::Target;
fn with_max_page_no(self, session: &Session) -> Self::Target;
fn with_min_page_no(self, session: &Session) -> Self::Target;
fn with_export(self, session: &Session) -> Self::Target;
}
pub trait PageExt<T> {
fn first(&self) -> Option<&T>;
fn first_mut(&mut self) -> Option<&mut T>;
fn take_first(&mut self) -> Option<T>;
fn into_first(self) -> Option<T>;
fn last(&self) -> Option<&T>;
fn last_mut(&mut self) -> Option<&mut T>;
fn take_last(&mut self) -> Option<T>;
fn into_last(self) -> Option<T>;
fn from_records_with_total(records: Vec<T>, page_num: u64, page_size: u64, total: u64) -> Self
where
Self: Sized;
fn from_records_without_total(records: Vec<T>, page_num: u64, page_size: u64) -> Self
where
Self: Sized;
}
pub trait PageExtMap<T, U> {
type MapTo;
fn map<F: Fn(T) -> U + Copy + Clone>(self, f: F) -> Self::MapTo;
}
#[cfg(all(feature = "rbatis", feature = "rbs"))]
mod rbatis {
use rbatis::sql::{Page, PageRequest};
use crate::tina::{constant::Constants, data::AppResult, server::session::Session};
use super::{PageExt, PageExtMap, PageRequestExt};
impl PageRequestExt for PageRequest {
type Target = AppResult<PageRequest>;
fn max_records(session: &Session) -> Self::Target {
let application = session.get_application();
let server_config = application.get_server_config()?;
let mut page = PageRequest::new(1, server_config.max_query_rows);
page.search_count = false;
Ok(page)
}
fn min_records(_session: &Session) -> Self::Target {
let mut page = PageRequest::new(1, 1);
page.search_count = false;
Ok(page)
}
fn max_page_no(_session: &Session) -> Self::Target {
let mut page = PageRequest::new(u64::MAX, Constants::DEFAULT_PAGE_SIZE);
page.search_count = false;
Ok(page)
}
fn min_page_no(_session: &Session) -> Self::Target {
let mut page = PageRequest::new(1, Constants::DEFAULT_PAGE_SIZE);
page.search_count = false;
Ok(page)
}
fn export(session: &Session) -> Self::Target {
let mut page = PageRequest::max_records(session)?;
page.search_count = true;
Ok(page)
}
fn with_max_records(mut self, session: &Session) -> Self::Target {
let application = session.get_application();
let server_config = application.get_server_config()?;
self.page_size = server_config.max_query_rows;
Ok(self)
}
fn with_min_records(mut self, _session: &Session) -> Self::Target {
self.page_size = 1;
Ok(self)
}
fn with_max_page_no(mut self, _session: &Session) -> Self::Target {
self.page_no = u64::MAX;
Ok(self)
}
fn with_min_page_no(mut self, _session: &Session) -> Self::Target {
self.page_no = 1;
Ok(self)
}
fn with_export(self, session: &Session) -> Self::Target {
Self::export(session)
}
}
impl<T> PageExt<T> for Page<T> {
fn first(&self) -> Option<&T> {
match self.records.is_empty() {
true => None,
false => self.records.first(),
}
}
fn first_mut(&mut self) -> Option<&mut T> {
match self.records.is_empty() {
true => None,
false => self.records.first_mut(),
}
}
fn take_first(&mut self) -> Option<T> {
match self.records.is_empty() {
true => None,
false => Some(self.records.remove(0)),
}
}
fn into_first(mut self) -> Option<T> {
match self.records.is_empty() {
true => None,
false => Some(self.records.remove(0)),
}
}
fn last(&self) -> Option<&T> {
match self.records.is_empty() {
true => None,
false => self.records.last(),
}
}
fn last_mut(&mut self) -> Option<&mut T> {
match self.records.is_empty() {
true => None,
false => self.records.last_mut(),
}
}
fn take_last(&mut self) -> Option<T> {
match self.records.is_empty() {
true => None,
false => Some(self.records.remove(self.records.len() - 1)),
}
}
fn into_last(mut self) -> Option<T> {
match self.records.is_empty() {
true => None,
false => Some(self.records.remove(self.records.len() - 1)),
}
}
fn from_records_with_total(records: Vec<T>, page_num: u64, page_size: u64, total: u64) -> Self
where
Self: Sized,
{
let add = match total % page_size > 0 {
true => 1,
false => 0,
};
let pages = (total / page_size) + add;
Self {
records,
total,
pages,
page_no: page_num,
page_size,
search_count: true,
}
}
fn from_records_without_total(records: Vec<T>, page_num: u64, page_size: u64) -> Self
where
Self: Sized,
{
let len = records.len() as u64;
let pages = match len >= page_size {
true => page_num + 1,
false => page_num,
};
let total = match len >= page_size {
true => page_num * page_size + 1,
false => {
let page_index = match page_num > 0 {
true => page_num - 1,
false => 0,
};
page_index * page_size + len
}
};
Self {
records,
total,
pages,
page_no: page_num,
page_size,
search_count: false,
}
}
}
impl<T, U> PageExtMap<T, U> for Page<T> {
type MapTo = Page<U>;
fn map<F: Fn(T) -> U + Copy + Clone>(self, f: F) -> Self::MapTo {
Self::MapTo {
records: self.records.into_iter().map(f).collect(),
total: self.total,
pages: self.pages,
page_no: self.page_no,
page_size: self.page_size,
search_count: self.search_count,
}
}
}
}