cat_gateway/db/event/common/
query_limits.rs

1//! `QueryLimits` query argument object.
2
3use std::fmt::Display;
4
5use crate::service::common::types::generic::query::pagination::{Limit, Page};
6
7/// A query limits struct.
8pub(crate) struct QueryLimits(QueryLimitsInner);
9
10/// `QueryLimits` inner enum representation.
11enum QueryLimitsInner {
12    /// Return all entries without any `LIMIT` and `OFFSET` parameters
13    All,
14    /// Specifies `LIMIT` parameter
15    Limit(u32),
16    /// Specifies `LIMIT` and `OFFSET` parameters
17    LimitAndOffset(u32, u32),
18}
19
20impl Display for QueryLimits {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        match self.0 {
23            QueryLimitsInner::All => write!(f, ""),
24            QueryLimitsInner::Limit(limit) => write!(f, "LIMIT {limit}"),
25            QueryLimitsInner::LimitAndOffset(limit, offset) => {
26                write!(f, "LIMIT {limit} OFFSET {offset}")
27            },
28        }
29    }
30}
31
32impl QueryLimits {
33    /// Create a `QueryLimits` object without the any limits.
34    #[allow(dead_code)]
35    pub(crate) const ALL: QueryLimits = Self(QueryLimitsInner::All);
36    /// Create a `QueryLimits` object with the limit equals to `1`.
37    #[allow(dead_code)]
38    pub(crate) const ONE: QueryLimits = Self(QueryLimitsInner::Limit(1));
39
40    /// Create a `QueryLimits` object from the service `Limit` and `Page` values.
41    pub(crate) fn new(limit: Option<Limit>, page: Option<Page>) -> Self {
42        match (limit, page) {
43            (Some(limit), Some(page)) => {
44                Self(QueryLimitsInner::LimitAndOffset(
45                    limit.into(),
46                    cal_offset(limit.into(), page.into()),
47                ))
48            },
49            (Some(limit), None) => {
50                Self(QueryLimitsInner::LimitAndOffset(
51                    limit.into(),
52                    Page::default().into(),
53                ))
54            },
55            (None, Some(page)) => {
56                let limit = Limit::default();
57
58                Self(QueryLimitsInner::LimitAndOffset(
59                    limit.into(),
60                    cal_offset(limit.into(), page.into()),
61                ))
62            },
63            (None, None) => {
64                Self(QueryLimitsInner::LimitAndOffset(
65                    Limit::default().into(),
66                    Page::default().into(),
67                ))
68            },
69        }
70    }
71}
72
73/// Calculate the offset value from page and limit.
74/// offset = limit * page
75fn cal_offset(page: u32, limit: u32) -> u32 {
76    limit.saturating_mul(page)
77}