queryweave_api/page.rs
1//! A page of items, as returned by a paginated query.
2
3// Scoped to this module: a derive's output is a separate item, out of reach of
4// an attribute on the struct.
5#![cfg_attr(
6 feature = "utoipa",
7 allow(
8 clippy::option_if_let_else,
9 reason = "utoipa's `ToSchema` expands the generic `items` field's schema to an if-let/else"
10 )
11)]
12
13// Unbounded: each integration's derive bounds its own impl (e.g. `Serialize`
14// for `T: Serialize`). Not part of the doc comment, which utoipa publishes.
15/// A page of items, as returned by a paginated query.
16#[derive(Debug, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize))]
18#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
19#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
20pub struct PageDto<T> {
21 /// The page returned (0 based), as requested.
22 pub page: Option<u32>,
23 /// The number of items per page, as requested.
24 pub page_size: Option<u32>,
25 /// The number of pages (none without a page size).
26 pub total_pages: Option<u32>,
27 /// The number of items over every page.
28 pub total_items: u32,
29 /// The items of the page.
30 pub items: Vec<T>,
31}
32
33impl<T> PageDto<T> {
34 /// A page of `items`, out of `total_items`, computing the number of pages.
35 #[must_use]
36 pub fn new(page: Option<u32>, page_size: Option<u32>, total_items: u32, items: Vec<T>) -> Self {
37 // A zero page size has no page count (and must not divide by zero).
38 let total_pages = page_size
39 .filter(|&page_size| page_size != 0)
40 .map(|page_size| total_items.div_ceil(page_size));
41
42 Self {
43 page,
44 page_size,
45 total_pages,
46 total_items,
47 items,
48 }
49 }
50}