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(
22        &self,
23        f: &mut std::fmt::Formatter<'_>,
24    ) -> std::fmt::Result {
25        match self.0 {
26            QueryLimitsInner::All => write!(f, ""),
27            QueryLimitsInner::Limit(limit) => write!(f, "LIMIT {limit}"),
28            QueryLimitsInner::LimitAndOffset(limit, offset) => {
29                write!(f, "LIMIT {limit} OFFSET {offset}")
30            },
31        }
32    }
33}
34
35impl QueryLimits {
36    /// Create a `QueryLimits` object without the any limits.
37    #[allow(dead_code)]
38    pub(crate) const ALL: QueryLimits = Self(QueryLimitsInner::All);
39    /// Create a `QueryLimits` object with the limit equals to `1`.
40    #[allow(dead_code)]
41    pub(crate) const ONE: QueryLimits = Self(QueryLimitsInner::Limit(1));
42
43    /// Create a `QueryLimits` object from the service `Limit` and `Page` values.
44    pub(crate) fn new(
45        limit: Option<Limit>,
46        page: Option<Page>,
47    ) -> Self {
48        match (limit, page) {
49            (Some(limit), Some(page)) => {
50                Self(QueryLimitsInner::LimitAndOffset(
51                    limit.into(),
52                    cal_offset(limit.into(), page.into()),
53                ))
54            },
55            (Some(limit), None) => {
56                Self(QueryLimitsInner::LimitAndOffset(
57                    limit.into(),
58                    Page::default().into(),
59                ))
60            },
61            (None, Some(page)) => {
62                let limit = Limit::default();
63
64                Self(QueryLimitsInner::LimitAndOffset(
65                    limit.into(),
66                    cal_offset(limit.into(), page.into()),
67                ))
68            },
69            (None, None) => {
70                Self(QueryLimitsInner::LimitAndOffset(
71                    Limit::default().into(),
72                    Page::default().into(),
73                ))
74            },
75        }
76    }
77}
78
79/// Calculate the offset value from page and limit.
80/// offset = limit * page
81fn cal_offset(
82    page: u32,
83    limit: u32,
84) -> u32 {
85    limit.saturating_mul(page)
86}