Skip to main content

arminius_lib_db/
query.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4//! Query utilities
5
6mod tests;
7
8/// The offset and limit of a query.
9#[derive(Clone, Copy, Debug)]
10pub struct Page {
11	/// the offset in the result set
12	offset: usize,
13	/// the maximum number of results to return
14	limit: usize,
15}
16
17impl Page {
18	/// the default page
19	pub const DEFAULT: Page = Page { offset: 0, limit: 100 };
20
21	/// Clamp `limit` to this value.
22	const MAX_PAGE_SIZE: usize = 500;
23
24	/// Constructs a new page.
25	#[must_use]
26	pub fn new(offset: usize, limit: usize) -> Self {
27		let limit =
28			if limit == 0 { Self::DEFAULT.limit } else { limit.clamp(0, Self::MAX_PAGE_SIZE) };
29		Self { offset, limit }
30	}
31
32	/// Returns the first page with a given size.
33	/// If limit is zero, the [`Self::DEFAULT`] limit will be used.
34	#[must_use]
35	pub fn top(limit: usize) -> Page {
36		Page::new(0, limit)
37	}
38
39	/// Returns the next page.
40	#[must_use]
41	pub fn next(&self) -> Page {
42		Page { offset: self.offset.saturating_add(self.limit), limit: self.limit }
43	}
44
45	/// sqlx-friendly representation of the offset
46	#[must_use]
47	pub fn offset(&self) -> i64 {
48		i64::try_from(self.offset).unwrap_or(i64::MAX)
49	}
50
51	/// sqlx-friendly representation of the limit
52	#[must_use]
53	pub fn limit(&self) -> i64 {
54		i64::try_from(self.limit).unwrap_or(i64::MAX)
55	}
56}
57
58impl Default for Page {
59	fn default() -> Page {
60		Self::DEFAULT
61	}
62}
63
64/// Possible ordering directions.
65#[derive(Debug, Default, PartialEq)]
66pub enum OrderDirection {
67	/// Ascending order. This is the default value.
68	#[default]
69	Ascending,
70	/// Descending order.
71	Descending,
72}
73
74impl OrderDirection {
75	/// Get the postgresql string representing the direction
76	#[must_use]
77	pub fn as_str(&self) -> &'static str {
78		match self {
79			OrderDirection::Ascending => "ASC",
80			OrderDirection::Descending => "DESC",
81		}
82	}
83}