rust-cutil 1.0.250090502

cutil
Documentation
use std::collections::HashMap;
use std::str::FromStr;

use crate::cutil::extract::Extract;
use crate::cutil::meta::R;
use crate::cutil::paged::Paged;
use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, PaginatorTrait, QueryOrder, Select};
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Pos {
  pub page_index: u64,
  pub page_size: u64,
  pub order_by: Vec<String>,
}

impl Pos {
  pub fn default() -> Self {
    Pos {
      page_index: 0,
      page_size: 10,
      order_by: vec![],
    }
  }
  pub fn first() -> Self {
    Pos {
      page_index: 0,
      page_size: 1,
      order_by: vec![],
    }
  }

  pub fn new(page_index: u64, page_size: u64, order_by: Vec<String>) -> Self {
    Pos {
      page_index,
      page_size,
      order_by,
    }
  }
  pub fn from(params: HashMap<String, String>) -> Self {
    let page_index = params.extract_u64_default("page_index", 0);
    let page_size = params.extract_u64_default("page_size", 10);
    let order_by: Vec<String> = params.extract_vec("order_by");

    Pos {
      page_index,
      page_size,
      order_by,
    }
  }

  pub async fn paged<M, E, D>(&self, conn: &DatabaseConnection, mut query: Select<E>) -> R<Paged<D>>
  where
    M: FromQueryResult + Send + Sync,
    E: EntityTrait,
    D: FromQueryResult + Send + Sync,
  {
    for item in &self.order_by {
      let list = item.split('.').collect::<Vec<_>>();
      if list.len() != 2 {
        continue;
      }

      let (column_name, sort_direction) = (list[0], list[1]);

      if let Ok(column) = E::Column::from_str(column_name) {
        query = match sort_direction.to_lowercase().as_str() {
          "asc" => query.order_by_asc(column),
          _ => query.order_by_desc(column),
        };
      }
    }
    let page_size = if self.page_size == 0 { 1 } else { self.page_size };
    let query = query.into_model::<D>();
    let paginator = query.paginate(conn, page_size);

    let items: Vec<D> = paginator.fetch_page(self.page_index).await?;

    let num = paginator.num_items_and_pages().await?;

    let paged = Paged {
      page_index: self.page_index,
      page_size,
      page_count: num.number_of_pages,
      items,
      item_count: num.number_of_items,
    };
    Ok(paged)
  }
}