sqlxo_traits/
web.rs

1use serde::{
2	Deserialize,
3	Serialize,
4};
5use utoipa::{
6	IntoParams,
7	PartialSchema,
8	ToSchema,
9};
10
11pub trait WebQueryModel {
12	type Leaf: ToSchema
13		+ Clone
14		+ serde::Serialize
15		+ for<'de> serde::Deserialize<'de>;
16	type SortField: ToSchema
17		+ Clone
18		+ serde::Serialize
19		+ for<'de> serde::Deserialize<'de>;
20}
21
22pub trait WebSortAccess: WebQueryModel {
23	fn sort_field(s: &DtoSort<Self>) -> <Self as WebQueryModel>::SortField;
24	fn sort_dir(s: &DtoSort<Self>) -> DtoSortDir;
25}
26
27#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
28#[serde(untagged)]
29pub enum GenericDtoExpression<Q> {
30	#[schema(no_recursion)]
31	And {
32		and: Vec<GenericDtoExpression<Q>>,
33	},
34	#[schema(no_recursion)]
35	Or {
36		or: Vec<GenericDtoExpression<Q>>,
37	},
38	Leaf(Q),
39}
40
41#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
42#[schema(bound = "S: ToSchema")]
43#[serde(transparent)]
44pub struct GenericDtoSort<S>(pub S);
45
46#[derive(Clone, Copy, Serialize, Deserialize, ToSchema, Debug)]
47#[serde(rename_all = "lowercase")]
48pub enum DtoSortDir {
49	Asc,
50	Desc,
51}
52
53#[derive(Clone, Copy, Serialize, Deserialize, ToSchema, Debug)]
54#[serde(rename_all = "camelCase")]
55pub struct DtoPage {
56	pub page_size: u32,
57	pub page_no:   u32,
58}
59
60impl Default for DtoPage {
61	fn default() -> Self {
62		Self {
63			page_size: u32::MAX,
64			page_no:   0,
65		}
66	}
67}
68
69#[derive(Clone, Serialize, Deserialize, ToSchema, Debug, IntoParams)]
70pub struct GenericDtoFilter<Q, S>
71where
72	Q: PartialSchema + ToSchema,
73	S: PartialSchema + ToSchema,
74{
75	#[schema(no_recursion)]
76	pub filter: Option<GenericDtoExpression<Q>>,
77	#[schema(no_recursion)]
78	pub sort:   Option<Vec<GenericDtoSort<S>>>,
79	pub page:   Option<DtoPage>,
80}
81
82pub type DtoExpression<T> = GenericDtoExpression<<T as WebQueryModel>::Leaf>;
83
84pub type DtoSort<T> = GenericDtoSort<<T as WebQueryModel>::SortField>;
85
86pub type DtoFilter<T> = GenericDtoFilter<
87	<T as WebQueryModel>::Leaf,
88	<T as WebQueryModel>::SortField,
89>;