use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
#[non_exhaustive]
pub struct Page<T> {
#[serde(default = "Vec::new")]
pub data: Vec<T>,
#[serde(default)]
pub page: u32,
#[serde(default)]
pub page_size: u32,
#[serde(default)]
pub total: u64,
#[serde(default)]
pub total_pages: u32,
}
impl<T> Page<T> {
pub fn has_next(&self) -> bool {
self.page < self.total_pages
}
pub fn has_prev(&self) -> bool {
self.page > 1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_envelope() {
let p: Page<u64> = serde_json::from_str(
r#"{"data":[1,2],"page":1,"page_size":2,"total":5,"total_pages":3}"#,
)
.unwrap();
assert_eq!(p.data, vec![1, 2]);
assert_eq!(p.page, 1);
assert_eq!(p.page_size, 2);
assert_eq!(p.total, 5);
assert_eq!(p.total_pages, 3);
}
#[test]
fn has_next_and_prev_track_position() {
let mid: Page<u64> =
serde_json::from_str(r#"{"data":[],"page":2,"total_pages":3}"#).unwrap();
assert!(mid.has_next());
assert!(mid.has_prev());
let first: Page<u64> =
serde_json::from_str(r#"{"data":[],"page":1,"total_pages":3}"#).unwrap();
assert!(first.has_next());
assert!(!first.has_prev());
let last: Page<u64> =
serde_json::from_str(r#"{"data":[],"page":3,"total_pages":3}"#).unwrap();
assert!(!last.has_next());
assert!(last.has_prev());
}
#[test]
fn empty_page_has_no_neighbours() {
let empty: Page<u64> = serde_json::from_str(r#"{"data":[]}"#).unwrap();
assert!(!empty.has_next());
assert!(!empty.has_prev());
}
#[test]
fn tolerates_missing_fields() {
let p: Page<u64> = serde_json::from_str(r#"{"data":[]}"#).unwrap();
assert!(p.data.is_empty());
assert_eq!(p.total_pages, 0);
}
}