1use crate::httpx::request::OnBehalfOfInfo;
20use crate::searchx::facets::Facet;
21use crate::searchx::queries::Query;
22use crate::searchx::sort::Sort;
23use serde::ser::{SerializeMap, SerializeSeq};
24use serde::{Serialize, Serializer};
25use std::collections::HashMap;
26
27#[derive(Debug, Clone, PartialEq)]
28#[non_exhaustive]
29pub struct Location {
30 pub lat: f64,
31 pub lon: f64,
32}
33
34impl Location {
35 pub fn new(lat: f64, lon: f64) -> Self {
36 Self { lat, lon }
37 }
38}
39
40impl Serialize for Location {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: Serializer,
44 {
45 let mut seq = serializer.serialize_seq(Some(2))?;
46 seq.serialize_element(&self.lon)?;
47 seq.serialize_element(&self.lat)?;
48
49 seq.end()
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
54#[serde(rename_all = "lowercase")]
55#[non_exhaustive]
56pub enum HighlightStyle {
57 Html,
58 Ansi,
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
62#[non_exhaustive]
63pub enum ConsistencyLevel {
64 #[serde(rename = "")]
65 NotBounded,
66 #[serde(rename = "at_plus")]
67 AtPlus,
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
71#[serde(rename_all = "lowercase")]
72#[non_exhaustive]
73pub enum ConsistencyResults {
74 Complete,
75}
76
77#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize)]
78#[non_exhaustive]
79pub struct Highlight {
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub style: Option<HighlightStyle>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub fields: Option<Vec<String>>,
84}
85
86impl Highlight {
87 pub fn new() -> Self {
88 Default::default()
89 }
90
91 pub fn style(mut self, style: impl Into<Option<HighlightStyle>>) -> Self {
92 self.style = style.into();
93 self
94 }
95
96 pub fn fields(mut self, fields: impl Into<Option<Vec<String>>>) -> Self {
97 self.fields = fields.into();
98 self
99 }
100}
101
102pub type ConsistencyVectors = HashMap<String, HashMap<String, u64>>;
103
104#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize)]
105#[non_exhaustive]
106pub struct Consistency {
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub level: Option<ConsistencyLevel>,
109 #[serde(skip_serializing_if = "Option::is_none")]
110 pub results: Option<ConsistencyResults>,
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub vectors: Option<ConsistencyVectors>,
113}
114
115impl Consistency {
116 pub fn new() -> Self {
117 Default::default()
118 }
119
120 pub fn level(mut self, level: impl Into<Option<ConsistencyLevel>>) -> Self {
121 self.level = level.into();
122 self
123 }
124
125 pub fn results(mut self, results: impl Into<Option<ConsistencyResults>>) -> Self {
126 self.results = results.into();
127 self
128 }
129
130 pub fn vectors(mut self, vectors: impl Into<Option<ConsistencyVectors>>) -> Self {
131 self.vectors = vectors.into();
132 self
133 }
134}
135
136#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize)]
137#[non_exhaustive]
138pub struct Control {
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub consistency: Option<Consistency>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub timeout: Option<u64>,
143}
144
145impl Control {
146 pub fn new() -> Self {
147 Default::default()
148 }
149
150 pub fn consistency(mut self, consistency: impl Into<Option<Consistency>>) -> Self {
151 self.consistency = consistency.into();
152 self
153 }
154
155 pub fn timeout(mut self, timeout: impl Into<Option<u64>>) -> Self {
156 self.timeout = timeout.into();
157 self
158 }
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize)]
162#[non_exhaustive]
163pub struct KnnQuery {
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub boost: Option<f32>,
166 pub field: String,
167 pub k: i64,
168 #[serde(skip_serializing_if = "Option::is_none")]
169 pub vector: Option<Vec<f32>>,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub vector_base64: Option<String>,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub filter: Option<Query>,
174}
175
176impl KnnQuery {
177 pub fn new(field: impl Into<String>, k: impl Into<i64>) -> Self {
178 Self {
179 boost: None,
180 field: field.into(),
181 k: k.into(),
182 vector: None,
183 vector_base64: None,
184 filter: None,
185 }
186 }
187
188 pub fn boost(mut self, boost: impl Into<Option<f32>>) -> Self {
189 self.boost = boost.into();
190 self
191 }
192
193 pub fn k(mut self, k: impl Into<i64>) -> Self {
194 self.k = k.into();
195 self
196 }
197
198 pub fn vector(mut self, vector: impl Into<Option<Vec<f32>>>) -> Self {
199 self.vector = vector.into();
200 self
201 }
202
203 pub fn vector_base64(mut self, vector_base64: impl Into<Option<String>>) -> Self {
204 self.vector_base64 = vector_base64.into();
205 self
206 }
207
208 pub fn filter(mut self, filter: impl Into<Option<Query>>) -> Self {
209 self.filter = filter.into();
210 self
211 }
212}
213
214#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
215#[serde(rename_all = "lowercase")]
216#[non_exhaustive]
217pub enum KnnOperator {
218 Or,
219 And,
220}
221
222#[derive(Debug, Default, Clone, PartialEq, Serialize)]
223#[non_exhaustive]
224pub struct QueryOptions {
225 #[serde(skip_serializing_if = "Option::is_none")]
226 pub(crate) collections: Option<Vec<String>>,
227 #[serde(skip_serializing_if = "Option::is_none", rename = "ctl")]
228 pub(crate) control: Option<Control>,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub(crate) explain: Option<bool>,
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub(crate) facets: Option<HashMap<String, Facet>>,
233 #[serde(skip_serializing_if = "Option::is_none")]
234 pub(crate) fields: Option<Vec<String>>,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub(crate) from: Option<u32>,
237 #[serde(skip_serializing_if = "Option::is_none")]
238 pub(crate) highlight: Option<Highlight>,
239 #[serde(skip_serializing_if = "Option::is_none", rename = "includeLocations")]
240 pub(crate) include_locations: Option<bool>,
241 #[serde(skip_serializing_if = "Option::is_none")]
242 pub(crate) query: Option<Query>,
243 #[serde(skip_serializing_if = "Option::is_none")]
244 pub(crate) score: Option<String>,
245 #[serde(skip_serializing_if = "Option::is_none")]
246 pub(crate) search_after: Option<Vec<String>>,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub(crate) search_before: Option<Vec<String>>,
249 #[serde(skip_serializing_if = "Option::is_none", rename = "showrequest")]
250 pub(crate) show_request: Option<bool>,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub(crate) size: Option<u32>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub(crate) sort: Option<Vec<Sort>>,
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub(crate) knn: Option<Vec<KnnQuery>>,
257 #[serde(skip_serializing_if = "Option::is_none")]
258 pub(crate) knn_operator: Option<KnnOperator>,
259
260 #[serde(skip_serializing_if = "Option::is_none", flatten)]
261 pub(crate) raw: Option<HashMap<String, serde_json::Value>>,
262
263 #[serde(skip_serializing)]
264 pub(crate) index_name: String,
265 #[serde(skip_serializing)]
266 pub(crate) scope_name: Option<String>,
267 #[serde(skip_serializing)]
268 pub(crate) bucket_name: Option<String>,
269
270 #[serde(skip_serializing)]
271 pub(crate) on_behalf_of: Option<OnBehalfOfInfo>,
272}
273
274impl QueryOptions {
275 pub fn new(index_name: impl Into<String>) -> Self {
276 Self {
277 collections: None,
278 control: None,
279 explain: None,
280 facets: None,
281 fields: None,
282 from: None,
283 highlight: None,
284 include_locations: None,
285 query: None,
286 score: None,
287 search_after: None,
288 search_before: None,
289 show_request: None,
290 size: None,
291 sort: None,
292 knn: None,
293 knn_operator: None,
294 raw: None,
295 index_name: index_name.into(),
296 scope_name: None,
297 bucket_name: None,
298 on_behalf_of: None,
299 }
300 }
301
302 pub fn collections(mut self, collections: impl Into<Option<Vec<String>>>) -> Self {
303 self.collections = collections.into();
304 self
305 }
306
307 pub fn control(mut self, control: impl Into<Option<Control>>) -> Self {
308 self.control = control.into();
309 self
310 }
311
312 pub fn explain(mut self, explain: impl Into<Option<bool>>) -> Self {
313 self.explain = explain.into();
314 self
315 }
316
317 pub fn facets(mut self, facets: impl Into<Option<HashMap<String, Facet>>>) -> Self {
318 self.facets = facets.into();
319 self
320 }
321
322 pub fn fields(mut self, fields: impl Into<Option<Vec<String>>>) -> Self {
323 self.fields = fields.into();
324 self
325 }
326
327 pub fn from(mut self, from: impl Into<Option<u32>>) -> Self {
328 self.from = from.into();
329 self
330 }
331
332 pub fn highlight(mut self, highlight: impl Into<Option<Highlight>>) -> Self {
333 self.highlight = highlight.into();
334 self
335 }
336
337 pub fn include_locations(mut self, include_locations: impl Into<Option<bool>>) -> Self {
338 self.include_locations = include_locations.into();
339 self
340 }
341
342 pub fn query(mut self, query: impl Into<Option<Query>>) -> Self {
343 self.query = query.into();
344 self
345 }
346
347 pub fn score(mut self, score: impl Into<Option<String>>) -> Self {
348 self.score = score.into();
349 self
350 }
351
352 pub fn search_after(mut self, search_after: impl Into<Option<Vec<String>>>) -> Self {
353 self.search_after = search_after.into();
354 self
355 }
356
357 pub fn search_before(mut self, search_before: impl Into<Option<Vec<String>>>) -> Self {
358 self.search_before = search_before.into();
359 self
360 }
361
362 pub fn show_request(mut self, show_request: impl Into<Option<bool>>) -> Self {
363 self.show_request = show_request.into();
364 self
365 }
366
367 pub fn size(mut self, size: impl Into<Option<u32>>) -> Self {
368 self.size = size.into();
369 self
370 }
371
372 pub fn sort(mut self, sort: impl Into<Option<Vec<Sort>>>) -> Self {
373 self.sort = sort.into();
374 self
375 }
376
377 pub fn knn(mut self, knn: impl Into<Option<Vec<KnnQuery>>>) -> Self {
378 self.knn = knn.into();
379 self
380 }
381
382 pub fn knn_operator(mut self, knn_operator: impl Into<Option<KnnOperator>>) -> Self {
383 self.knn_operator = knn_operator.into();
384 self
385 }
386
387 pub fn raw(mut self, raw: impl Into<Option<HashMap<String, serde_json::Value>>>) -> Self {
388 self.raw = raw.into();
389 self
390 }
391
392 pub fn scope_name(mut self, scope_name: impl Into<Option<String>>) -> Self {
393 self.scope_name = scope_name.into();
394 self
395 }
396
397 pub fn bucket_name(mut self, bucket_name: impl Into<Option<String>>) -> Self {
398 self.bucket_name = bucket_name.into();
399 self
400 }
401
402 pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<OnBehalfOfInfo>>) -> Self {
403 self.on_behalf_of = on_behalf_of.into();
404 self
405 }
406}