Skip to main content

miryad_core/
query.rs

1//! Pagination partagée par REST (feature 4), et plus tard GraphQL/MCP — volontairement pas dans
2//! `rest/`, pour éviter de la dupliquer quand ces autres couches en auront besoin.
3
4pub const DEFAULT_PER_PAGE: u64 = 100;
5pub const MAX_PER_PAGE: u64 = 1000;
6
7/// Paramètres de pagination normalisés — l'objectif n'est pas une pagination fine, juste
8/// d'empêcher qu'une liste ne remonte des milliers de lignes d'un coup.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct Pagination {
11    /// 1-indexée côté API.
12    pub page: u64,
13    pub per_page: u64,
14}
15
16impl Pagination {
17    /// Construit depuis des query params bruts, potentiellement absents ou hors bornes.
18    /// `page` clampée à un minimum de 1, `per_page` clampée à `[1, MAX_PER_PAGE]`.
19    pub fn from_raw(page: Option<u64>, per_page: Option<u64>) -> Self {
20        let page = page.unwrap_or(1).max(1);
21        let per_page = per_page.unwrap_or(DEFAULT_PER_PAGE).clamp(1, MAX_PER_PAGE);
22        Self { page, per_page }
23    }
24}
25
26/// Page de résultats, avec assez de métadonnées pour qu'un client sache s'il en reste d'autres.
27#[derive(Debug, Clone, serde::Serialize)]
28pub struct PagedResult<M> {
29    pub items: Vec<M>,
30    pub page: u64,
31    pub per_page: u64,
32    pub total_items: u64,
33    pub total_pages: u64,
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn defaults_when_absent() {
42        let p = Pagination::from_raw(None, None);
43        assert_eq!(p.page, 1);
44        assert_eq!(p.per_page, DEFAULT_PER_PAGE);
45    }
46
47    #[test]
48    fn per_page_clamped_to_max() {
49        let p = Pagination::from_raw(None, Some(50_000));
50        assert_eq!(p.per_page, MAX_PER_PAGE);
51    }
52
53    #[test]
54    fn per_page_clamped_to_min() {
55        let p = Pagination::from_raw(None, Some(0));
56        assert_eq!(p.per_page, 1);
57    }
58
59    #[test]
60    fn page_clamped_to_min() {
61        let p = Pagination::from_raw(Some(0), None);
62        assert_eq!(p.page, 1);
63    }
64}