remendo/models/
pagination.rs1use serde::Deserialize;
4
5#[derive(Debug, Clone, PartialEq, Deserialize)]
26pub struct Paginated<T> {
27 pub items: Vec<T>,
29 #[serde(default)]
31 pub total: u32,
32 #[serde(default)]
34 pub page: u32,
35 #[serde(default)]
37 pub per_page: u32,
38}
39
40impl<T> Paginated<T> {
41 #[must_use]
43 pub fn total_pages(&self) -> u32 {
44 if self.per_page == 0 {
45 return 1;
46 }
47 self.total.div_ceil(self.per_page)
48 }
49}
50
51#[cfg(test)]
52#[allow(clippy::expect_used)]
53mod tests {
54 use super::*;
55 use crate::models::Patchset;
56
57 #[test]
58 fn deserialize_paginated_patchsets() {
59 let json = r#"{
60 "items": [{
61 "id": 19555,
62 "subject": "[PATCH v2 0/4] iio: light: fix null pointer",
63 "status": "Pending",
64 "author": "dev@example.com",
65 "date": 1778690980,
66 "total_parts": 4,
67 "received_parts": 4,
68 "subsystems": ["LKML", "linux-iio"],
69 "findings_low": 0,
70 "findings_medium": 1,
71 "findings_high": 0,
72 "findings_critical": 0
73 }],
74 "total": 19558,
75 "page": 1,
76 "per_page": 50
77 }"#;
78 let paginated: Paginated<Patchset> =
79 serde_json::from_str(json).expect("deserialize paginated");
80 assert_eq!(paginated.items.len(), 1);
81 assert_eq!(paginated.total, 19558);
82 assert_eq!(paginated.page, 1);
83 assert_eq!(paginated.per_page, 50);
84 }
85
86 #[test]
87 fn deserialize_empty_paginated() {
88 let json = r#"{"items": [], "total": 0, "page": 1, "per_page": 50}"#;
89 let paginated: Paginated<Patchset> =
90 serde_json::from_str(json).expect("deserialize empty paginated");
91 assert!(paginated.items.is_empty());
92 assert_eq!(paginated.total, 0);
93 }
94}