use std::fmt::Debug;
use field_access::FieldAccess;
use serde::{Deserialize, Serialize};
use crate::common::{conversion::ValueConvert, fields::get_value};
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash)]
pub enum Order {
#[serde(rename = "ASC")]
#[default]
Asc,
#[serde(rename = "DESC")]
Desc
}
impl Order {
pub fn as_str(&self) -> &str {
match self {
Order::Asc => "ASC",
Order::Desc => "DESC",
}
}
}
#[derive(Debug, Clone)]
pub enum JoinType {
Inner,
Left,
Right,
Full,
Cross
}
#[derive(Debug, Clone)]
pub enum PrimaryKey<'a> {
Single(&'a str, bool),
Composite(&'a [&'a str]),
}
impl <'a> PrimaryKey<'a> {
pub fn get_keys(&self) -> Vec<&'a str> {
match self {
PrimaryKey::Single(key, _) => vec![key],
PrimaryKey::Composite(keys) => keys.iter().map(|x| *x).collect(),
}
}
pub fn auto_generate(&self) -> bool {
match self {
PrimaryKey::Single(_, flag) => *flag,
PrimaryKey::Composite(_) => false,
}
}
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash)]
pub struct PaginatedResult<T> {
pub data: Vec<T>,
pub total: u64,
pub page_number: u64,
pub page_size: u64,
}
impl<T> PaginatedResult<T> {
pub fn new(data: Vec<T>, total: u64, page_number: u64, page_size: u64) -> Self {
Self {
data,
total,
page_number,
page_size,
}
}
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq, Eq, Hash)]
pub struct CursorPaginatedResult<T, C> {
pub data: Vec<T>,
pub next_cursor: Option<C>,
pub prev_cursor: Option<C>,
pub limit: u64,
pub sort_order: Order,
}
impl<T, C> CursorPaginatedResult<T, C> {
pub fn new(data: Vec<T>, limit: u64, sort_order: Order) -> Self {
Self {
data,
next_cursor: None,
prev_cursor: None,
limit,
sort_order,
}
}
pub fn has_next_page(&self) -> bool {
self.next_cursor.is_some() && !self.data.is_empty()
}
pub fn has_prev_page(&self) -> bool {
self.prev_cursor.is_some() && !self.data.is_empty()
}
pub fn gen_cursors(&mut self, column_key: &str)
where
T: FieldAccess,
C: ValueConvert + Default,
{
if self.data.len() as u64 == self.limit {
let (next_item, prev_item) = match self.sort_order {
Order::Asc => (self.data.last(), self.data.first()),
Order::Desc => (self.data.first(), self.data.last()),
};
self.next_cursor = next_item.map(|item| get_value::<T, C>(item, column_key));
self.prev_cursor = prev_item.map(|item| get_value::<T, C>(item, column_key));
}
}
}