liserk_shared/
query.rs

1use serde::{Deserialize, Serialize};
2
3/// Specifies the type of a `CompoundQuery`, defining how its `Query`s are combined.
4#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
5pub enum QueryType {
6    And,
7    Or,
8}
9
10/// The root Query type, which can be either a `SingleQuery` or a `CompoundQuery`.
11#[derive(Debug, Serialize, Deserialize, Clone)]
12pub enum Query {
13    Single(SingleQuery),
14    Compound(CompoundQuery),
15    GetById { id: String, collection: String },
16    GetByIds { ids: Vec<String>, collection: String },
17}
18
19impl PartialEq for Query {
20    fn eq(&self, other: &Self) -> bool {
21        match (self, other) {
22            (Self::Single(l0), Self::Single(r0)) => l0 == r0,
23            (Self::Compound(l0), Self::Compound(r0)) => l0 == r0,
24            (
25                Self::GetById { id: l_id, collection: l_collection },
26                Self::GetById { id: r_id, collection: r_collection },
27            ) => l_id == r_id && l_collection == r_collection,
28            (
29                Self::GetByIds { ids: l_ids, collection: l_collection },
30                Self::GetByIds { ids: r_ids, collection: r_collection },
31            ) => l_ids == r_ids && l_collection == r_collection,
32            _ => false,
33        }
34    }
35}
36
37impl Eq for Query {}
38
39/// Represents a single query on a collection for a given use case.
40///
41/// This is the basic unit of querying in this system.
42/// A `SingleQuery` operates on one collection and one use case.
43#[derive(Debug, Serialize, Deserialize, Clone)]
44pub struct SingleQuery {
45    pub collection: String,
46    pub usecase: String,
47    pub upper_limit: Option<f64>,
48    pub lower_limit: Option<f64>,
49}
50
51impl PartialEq for SingleQuery {
52    fn eq(&self, other: &Self) -> bool {
53        self.collection == other.collection
54            && self.usecase == other.usecase
55            && self.upper_limit == other.upper_limit
56            && self.lower_limit == other.lower_limit
57    }
58}
59
60impl Eq for SingleQuery {}
61
62impl SingleQuery {
63    /// Constructs a new `SingleQuery`.
64    ///
65    /// # Arguments
66    ///
67    /// * `collection` - A string specifying the collection to be queried.
68    /// * `usecase` - A string specifying the use case for the query.
69    ///
70    /// # Returns
71    ///
72    /// Returns a `SingleQuery` without OPE.
73    pub fn new(collection: String, usecase: String) -> Self {
74        SingleQuery {
75            collection,
76            usecase,
77            upper_limit: None,
78            lower_limit: None,
79        }
80    }
81}
82
83/// Represents a compound query composed of multiple `Query`s.
84///
85/// A `CompoundQuery` allows for complex query logic by combining multiple `Query`s
86/// using a specified `QueryType` (e.g., And, Or).
87#[derive(Debug, Serialize, Deserialize, Clone)]
88pub struct CompoundQuery {
89    pub query_type: QueryType,
90    pub queries: Vec<Query>,
91}
92
93impl PartialEq for CompoundQuery {
94    fn eq(&self, other: &Self) -> bool {
95        self.query_type == other.query_type && self.queries == other.queries
96    }
97}
98
99impl Eq for CompoundQuery {}
100
101/// Builder for `SingleQuery`
102#[derive(Debug, Default)]
103pub struct SingleQueryBuilder {
104    collection: String,
105    usecase: String,
106    upper_limit: Option<f64>,
107    lower_limit: Option<f64>,
108}
109
110impl SingleQueryBuilder {
111    pub fn with_collection(mut self, collection: String) -> Self {
112        self.collection = collection;
113        self
114    }
115
116    pub fn with_usecase(mut self, usecase: String) -> Self {
117        self.usecase = usecase;
118        self
119    }
120
121    pub fn with_encrypted_field_less_than(mut self, value: f64) -> Self {
122        self.upper_limit = Some(value);
123        self
124    }
125
126    pub fn with_encrypted_field_higher_than(mut self, value: f64) -> Self {
127        self.lower_limit = Some(value);
128        self
129    }
130
131    pub fn build(self) -> SingleQuery {
132        SingleQuery {
133            collection: self.collection,
134            usecase: self.usecase,
135            upper_limit: self.upper_limit,
136            lower_limit: self.lower_limit,
137        }
138    }
139}
140
141impl CompoundQuery {
142    /// Constructs a new `CompoundQuery`.
143    ///
144    /// # Arguments
145    ///
146    /// * `query_type` - A `QueryType` specifying how to combine the `queries`.
147    /// * `queries` - A Vec of `Query`s to be combined.
148    ///
149    /// # Returns
150    ///
151    /// Returns a `CompoundQuery`.
152    pub fn new(query_type: QueryType, queries: Vec<Query>) -> Self {
153        CompoundQuery { query_type, queries }
154    }
155}
156
157/// Builder for `CompoundQuery`
158#[derive(Debug)]
159pub struct CompoundQueryBuilder {
160    query_type: QueryType,
161    queries: Vec<Query>,
162}
163
164impl Default for CompoundQueryBuilder {
165    fn default() -> Self {
166        Self {
167            query_type: QueryType::And,
168            queries: Default::default(),
169        }
170    }
171}
172
173impl CompoundQueryBuilder {
174    pub fn with_query_type(mut self, query_type: QueryType) -> Self {
175        self.query_type = query_type;
176        self
177    }
178
179    pub fn with_query(mut self, query: Query) -> Self {
180        self.queries.push(query);
181        self
182    }
183
184    pub fn build(self) -> CompoundQuery {
185        CompoundQuery { query_type: self.query_type, queries: self.queries }
186    }
187}