//! 公共类型和工具函数 use serde::Serialize; /// 分页响应通用包装 #[derive(Debug, Serialize)] pub struct PaginatedResponse { pub items: Vec, pub total: i64, pub page: u32, pub page_size: u32, } /// 分页上限 pub const MAX_PAGE_SIZE: u32 = 100; /// 默认分页大小 pub const DEFAULT_PAGE_SIZE: u32 = 20; /// 规范化分页参数,返回 (page, page_size, offset) pub fn normalize_pagination(page: Option, page_size: Option) -> (u32, u32, i64) { let p = page.unwrap_or(1).max(1); let ps = page_size.unwrap_or(DEFAULT_PAGE_SIZE).min(MAX_PAGE_SIZE).max(1); let offset = ((p - 1) * ps) as i64; (p, ps, offset) } #[cfg(test)] mod tests { use super::*; #[test] fn test_normalize_pagination_defaults() { let (page, size, offset) = normalize_pagination(None, None); assert_eq!(page, 1); assert_eq!(size, DEFAULT_PAGE_SIZE); assert_eq!(offset, 0); } #[test] fn test_normalize_pagination_clamp() { let (page, size, offset) = normalize_pagination(None, Some(999)); assert_eq!(size, MAX_PAGE_SIZE); } #[test] fn test_normalize_pagination_offset() { let (page, size, offset) = normalize_pagination(Some(3), Some(10)); assert_eq!(offset, 20); } }