1use std::convert::TryFrom;
2
3use anyhow::anyhow;
4
5use interface::{BlobMeta, CertificateInfo, Query, StorageNodeInfo};
6
7use rapidquery::Expression;
8
9use serde::{Deserialize, Serialize};
10
11pub mod blobmeta {
12 use super::*;
13
14 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
15 #[serde(deny_unknown_fields)]
16 pub struct ListMetadataRequest {
17 pub tags: Option<Vec<String>>,
19
20 pub fields: Option<Vec<String>>,
22 }
23
24 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
25 #[serde(deny_unknown_fields)]
26 pub struct GetMetaResponse {
27 pub meta: Option<BlobMeta>,
28 }
29}
30
31pub mod routing {
32 use interface::RoutingConfig;
33
34 use super::*;
35
36 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
37 #[serde(deny_unknown_fields)]
38 pub struct GetRoutingConfigResponse {
39 pub routing_config: Option<RoutingConfig>,
40 }
41
42 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
43 #[serde(deny_unknown_fields)]
44 pub struct SetRoutingConfigRequest {
45 pub routing_config: RoutingConfig,
46 }
47}
48
49pub mod auth {
50 use super::*;
51
52 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
53 #[serde(deny_unknown_fields)]
54 pub struct LoginRequest {
55 pub username: String,
56 pub password: String,
57 }
58
59 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
60 #[serde(deny_unknown_fields)]
61 pub struct LoginResponse {
62 pub token: String,
63 }
64
65 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
66 #[serde(deny_unknown_fields)]
67 pub struct RegisterRequest {
68 pub username: String,
69 pub password: String,
70 }
71}
72
73pub mod storage {
74 use super::*;
75
76 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
77 #[serde(deny_unknown_fields)]
78 pub struct ListStorageNodesResponse {
79 pub storage_nodes: Vec<StorageNodeInfo>,
80 }
81
82 #[derive(Clone, Debug, Deserialize, Serialize)]
83 #[serde(deny_unknown_fields)]
84 pub struct MoveRequest {
85 pub blob_id: String,
86 pub destination_url: String,
87 pub owner_username: String,
88 }
89
90 #[derive(Clone, Debug, Deserialize, Serialize)]
91 #[serde(deny_unknown_fields)]
92 pub struct RegisterResponse {
93 pub message: String,
94 pub certificates: Option<CertificateInfo>,
95 pub rebuild_requested: bool,
96 pub move_requests: Vec<MoveRequest>,
97 }
98}
99
100pub mod query {
101 use interface::{ExpressionField, FieldValue, SortOrder};
102
103 use super::*;
104
105 #[derive(Clone, Debug, Deserialize, Hash, PartialEq, Eq, Serialize)]
106 #[serde(untagged)]
107 pub enum RawExpression {
108 Tag { tag: String },
112 Field { key: String, value: FieldValue },
116 HasField { key: String },
120 And {
124 and: (Box<RawExpression>, Box<RawExpression>),
125 },
126 Or {
129 or: (Box<RawExpression>, Box<RawExpression>),
130 },
131 Not { not: Box<RawExpression> },
134
135 Raw { raw: String },
137
138 Empty,
141 }
142
143 impl TryFrom<RawExpression> for Expression<ExpressionField> {
144 type Error = anyhow::Error;
145
146 fn try_from(value: RawExpression) -> Result<Self, Self::Error> {
147 let expr = match value {
148 RawExpression::Empty => Self::Empty,
149 RawExpression::Raw { raw } => {
150 Expression::parse(raw).map_err(|e| anyhow!("{}", e))?
151 }
152 RawExpression::Not { not } => Self::Not {
153 not: Box::new(Expression::try_from(*not)?),
154 },
155 RawExpression::Or { or: (a, b) } => Self::Or {
156 or: (
157 Box::new(Expression::try_from(*a)?),
158 Box::new(Expression::try_from(*b)?),
159 ),
160 },
161 RawExpression::And { and: (a, b) } => Self::And {
162 and: (
163 Box::new(Expression::try_from(*a)?),
164 Box::new(Expression::try_from(*b)?),
165 ),
166 },
167 RawExpression::HasField { key } => Self::Field(ExpressionField::HasField { key }),
168 RawExpression::Field { key, value } => {
169 Self::Field(ExpressionField::Field { key, value })
170 }
171 RawExpression::Tag { tag } => Self::Field(ExpressionField::Tag { tag }),
172 };
173
174 Ok(expr)
175 }
176 }
177
178 #[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
179 #[serde(deny_unknown_fields)]
180 #[serde(untagged)]
181 pub enum ExpressionRequest {
182 Expr(RawExpression),
183 Raw(String),
184 }
185
186 impl Default for ExpressionRequest {
187 fn default() -> Self {
188 ExpressionRequest::Expr(RawExpression::Empty)
189 }
190 }
191
192 fn default_from() -> usize {
193 0
194 }
195
196 fn default_size() -> usize {
197 30
198 }
199
200 fn default_sign_urls() -> bool {
201 true
202 }
203
204 fn default_facets() -> bool {
205 false
206 }
207
208 fn default_sort_order() -> SortOrder {
209 SortOrder::CreationAscending
210 }
211
212 #[derive(Clone, Debug, Deserialize, Hash, Serialize, PartialEq, Eq)]
213 #[serde(deny_unknown_fields)]
214 pub struct QueryRequest {
215 #[serde(default = "ExpressionRequest::default")]
216 pub expression: ExpressionRequest,
217
218 #[serde(default = "default_from")]
219 pub from: usize,
220
221 #[serde(default = "default_size")]
222 pub size: usize,
223
224 #[serde(default = "default_sign_urls")]
225 pub sign_urls: bool,
226
227 #[serde(default = "default_facets")]
228 pub facets: bool, #[serde(default = "default_sort_order")]
231 pub sort_order: SortOrder,
232 }
233
234 impl TryFrom<QueryRequest> for Query {
235 type Error = anyhow::Error;
236
237 fn try_from(request: QueryRequest) -> Result<Self, Self::Error> {
238 let expression = match request.expression {
239 ExpressionRequest::Expr(e) => Expression::try_from(e)?,
240 ExpressionRequest::Raw(raw) => Expression::parse(raw)?,
241 };
242
243 Ok(Query {
244 expression,
245 from: request.from,
246 size: request.size,
247 sign_urls: request.sign_urls,
248 facets: request.facets,
249 sort_order: request.sort_order,
250 })
251 }
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use interface::{Expression, ExpressionField};
258
259 use super::query::RawExpression;
260
261 #[test]
262 fn mixed_expression_parsing() {
263 let manual_expr = Expression::And {
264 and: (
265 Box::new(Expression::Field(ExpressionField::Tag { tag: "a".into() })),
266 Box::new(Expression::And {
267 and: (
268 Box::new(Expression::Field(ExpressionField::Tag { tag: "b".into() })),
269 Box::new(Expression::Field(ExpressionField::Tag { tag: "c".into() })),
270 ),
271 }),
272 ),
273 };
274
275 let auto_expr = Expression::try_from(RawExpression::And {
276 and: (
277 Box::new(RawExpression::Tag {
278 tag: String::from("a"),
279 }),
280 Box::new(RawExpression::Raw {
281 raw: String::from("b && c"),
282 }),
283 ),
284 })
285 .unwrap();
286
287 assert_eq!(manual_expr, auto_expr);
288 }
289}