use serde::{Deserialize, Serialize}; use utoipa::{IntoParams, ToSchema}; pub const DEFAULT_PAGE_LIMIT: u64 = 50; pub const MAX_PAGE_LIMIT: u64 = 100; pub const MAX_OFFSET: u64 = 5000; #[derive(Debug, Clone, Deserialize, IntoParams, ToSchema)] pub struct PageQuery { pub limit: Option, pub offset: Option, pub sort: Option, } impl PageQuery { pub fn limit(&self) -> u64 { self.limit .unwrap_or(DEFAULT_PAGE_LIMIT) .clamp(1, MAX_PAGE_LIMIT) } pub fn offset(&self) -> u64 { self.offset.unwrap_or(0).clamp(0, MAX_OFFSET) } pub fn page(&self) -> (u64, u64) { (self.limit(), self.offset()) } } #[derive(Debug, Clone, Serialize, ToSchema)] pub struct Page { pub items: Vec, pub total: i64, pub limit: u64, pub offset: u64, } pub fn paginate(items: Vec, page: &PageQuery) -> Page { let total = items.len() as i64; let (limit, offset) = page.page(); let items = items .into_iter() .skip(offset as usize) .take(limit as usize) .collect(); Page { items, total, limit, offset, } }