Files
Oxicloud/src/application/dtos/pagination.rs
T

103 lines
2.6 KiB
Rust
Raw Normal View History

2026-02-14 01:29:34 +01:00
use serde::{Deserialize, Serialize};
2025-03-19 00:44:27 +01:00
/// A DTO to represent pagination information
2025-03-19 00:44:27 +01:00
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationDto {
/// Current page (starts at 0)
2025-03-19 00:44:27 +01:00
pub page: usize,
/// Page size
2025-03-19 00:44:27 +01:00
pub page_size: usize,
/// Total number of items
2025-03-19 00:44:27 +01:00
pub total_items: usize,
/// Total number of pages
2025-03-19 00:44:27 +01:00
pub total_pages: usize,
/// Indicates if there is a next page
2025-03-19 00:44:27 +01:00
pub has_next: bool,
/// Indicates if there is a previous page
2025-03-19 00:44:27 +01:00
pub has_prev: bool,
}
/// A DTO to represent a pagination request
2025-03-19 00:44:27 +01:00
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationRequestDto {
/// Requested page (starts at 0)
2025-03-19 00:44:27 +01:00
#[serde(default)]
pub page: usize,
/// Requested page size
2025-03-19 00:44:27 +01:00
#[serde(default = "default_page_size")]
pub page_size: usize,
}
/// A DTO to represent a paginated response
2025-03-19 00:44:27 +01:00
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginatedResponseDto<T> {
/// Data on the current page
2025-03-19 00:44:27 +01:00
pub items: Vec<T>,
/// Pagination information
2025-03-19 00:44:27 +01:00
pub pagination: PaginationDto,
}
impl Default for PaginationRequestDto {
fn default() -> Self {
Self {
page: 0,
page_size: default_page_size(),
}
}
}
/// Function to set the default page size
2025-03-19 00:44:27 +01:00
fn default_page_size() -> usize {
100 // By default, 100 items per page
2025-03-19 00:44:27 +01:00
}
impl PaginationRequestDto {
/// Calculates the offset for paginated queries
2025-03-19 00:44:27 +01:00
pub fn offset(&self) -> usize {
self.page * self.page_size
}
2026-02-14 01:29:34 +01:00
/// Calculates the limit for paginated queries
2025-03-19 00:44:27 +01:00
pub fn limit(&self) -> usize {
self.page_size
}
2026-02-14 01:29:34 +01:00
/// Validates and adjusts the pagination parameters
2025-03-19 00:44:27 +01:00
pub fn validate_and_adjust(&self) -> Self {
let mut page = self.page;
let mut page_size = self.page_size;
2026-02-14 01:29:34 +01:00
// Ensure the page is at least 0
2025-03-19 00:44:27 +01:00
if page < 1 {
page = 0;
}
2026-02-14 01:29:34 +01:00
// Ensure the page size is between 10 and 500
page_size = page_size.clamp(10, 500);
2026-02-14 01:29:34 +01:00
Self { page, page_size }
2025-03-19 00:44:27 +01:00
}
}
impl<T> PaginatedResponseDto<T> {
/// Creates a new paginated response from the data and pagination information
2026-02-14 01:29:34 +01:00
pub fn new(items: Vec<T>, page: usize, page_size: usize, total_items: usize) -> Self {
2025-03-19 00:44:27 +01:00
let total_pages = if total_items == 0 {
0
} else {
total_items.div_ceil(page_size)
2025-03-19 00:44:27 +01:00
};
2026-02-14 01:29:34 +01:00
2025-03-19 00:44:27 +01:00
let pagination = PaginationDto {
page,
page_size,
total_items,
total_pages,
has_next: total_pages > 0 && page < total_pages - 1,
2025-03-19 00:44:27 +01:00
has_prev: page > 0,
};
2026-02-14 01:29:34 +01:00
Self { items, pagination }
2025-03-19 00:44:27 +01:00
}
2026-02-14 01:29:34 +01:00
}