mcsr_ranked_api/pagination/
mod.rs1use std::{error::Error, fmt::Display, num::NonZeroU8};
2
3use serde::Serialize;
4
5#[cfg(test)]
6mod tests;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum PaginationError {
11 Page(u8),
13 Count(u8),
15}
16
17impl Display for PaginationError {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 use PaginationError as Err;
20
21 match self {
22 Err::Page(p) => write!(f, "Page number {p} is not within bounds [0; 99]"),
23 Err::Count(c) => write!(f, "Item count {c} is not within bounds [1; 50]"),
24 }
25 }
26}
27impl Error for PaginationError {}
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
31#[serde(rename_all = "camelCase")]
32pub struct Pagination {
33 page: u8,
37 count: NonZeroU8,
41}
42
43impl Default for Pagination {
44 fn default() -> Self {
45 Self {
46 page: 0,
47 count: const { NonZeroU8::new(10).unwrap() },
48 }
49 }
50}
51
52impl Pagination {
53 pub fn new(page: u8, count: u8) -> Result<Self, PaginationError> {
60 let opt_count = NonZeroU8::new(count);
61 match (page, opt_count.map(|c| (c, c.get()))) {
62 (0..=99, Some((count, 1..=50))) => Ok(Self { page, count }),
63 (0..=99, _) => Err(PaginationError::Count(count)),
64 (_, _) => Err(PaginationError::Page(page)),
65 }
66 }
67
68 pub fn page(page: u8) -> Result<Self, PaginationError> {
70 match page {
71 0..=99 => Ok(Self {
72 page,
73 ..Default::default()
74 }),
75 _ => Err(PaginationError::Page(page)),
76 }
77 }
78
79 pub fn count(count: u8) -> Result<Self, PaginationError> {
81 let opt_count = NonZeroU8::new(count);
82 match opt_count.map(|c| (c, c.get())) {
83 Some((count, 1..=50)) => Ok(Self {
84 count,
85 ..Default::default()
86 }),
87 _ => Err(PaginationError::Count(count)),
88 }
89 }
90
91 pub unsafe fn new_unchecked(page: u8, count: u8) -> Self {
100 Self {
101 page,
102 count: unsafe { NonZeroU8::new_unchecked(count) },
103 }
104 }
105}