couchbase_core/queryx/
query_options.rs

1/*
2 *
3 *  * Copyright (c) 2025 Couchbase, Inc.
4 *  *
5 *  * Licensed under the Apache License, Version 2.0 (the "License");
6 *  * you may not use this file except in compliance with the License.
7 *  * You may obtain a copy of the License at
8 *  *
9 *  *    http://www.apache.org/licenses/LICENSE-2.0
10 *  *
11 *  * Unless required by applicable law or agreed to in writing, software
12 *  * distributed under the License is distributed on an "AS IS" BASIS,
13 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  * See the License for the specific language governing permissions and
15 *  * limitations under the License.
16 *
17 */
18
19use std::collections::HashMap;
20use std::sync::Arc;
21use std::time::Duration;
22
23use serde::ser::{SerializeMap, SerializeSeq};
24use serde::{Serialize, Serializer};
25use serde_json::Value;
26
27use crate::helpers;
28use crate::httpx::client::Client;
29use crate::httpx::request::OnBehalfOfInfo;
30use crate::mgmtx::node_target::NodeTarget;
31use crate::queryx::ensure_index_helper::DesiredState;
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
34#[serde(rename_all = "snake_case")]
35#[non_exhaustive]
36pub enum ScanConsistency {
37    NotBounded,
38    RequestPlus,
39    AtPlus,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
43#[serde(rename_all = "lowercase")]
44#[non_exhaustive]
45pub enum ProfileMode {
46    Off,
47    Phases,
48    Timings,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
52#[serde(rename_all = "UPPERCASE")]
53#[non_exhaustive]
54pub enum Compression {
55    Zip,
56    Rle,
57    Lzma,
58    Lzo,
59    None,
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
63#[serde(rename_all = "camelCase")]
64#[non_exhaustive]
65pub enum DurabilityLevel {
66    None,
67    Majority,
68    MajorityAndPersistActive,
69    PersistToMajority,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
73#[non_exhaustive]
74pub enum Encoding {
75    #[serde(rename = "UTF-8")]
76    Utf8,
77}
78
79#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
80#[serde(rename_all = "UPPERCASE")]
81#[non_exhaustive]
82pub enum Format {
83    Json,
84    Xml,
85    Csv,
86    Tsv,
87}
88
89#[derive(Debug, Clone, Serialize)]
90#[non_exhaustive]
91pub struct CredsJson {
92    #[serde(skip_serializing_if = "String::is_empty")]
93    pub(crate) user: String,
94    #[serde(skip_serializing_if = "String::is_empty")]
95    pub(crate) pass: String,
96}
97
98impl CredsJson {
99    pub fn new(user: impl Into<String>, pass: impl Into<String>) -> Self {
100        Self {
101            user: user.into(),
102            pass: pass.into(),
103        }
104    }
105}
106
107#[derive(Debug, Clone, Serialize)]
108#[serde(rename_all = "lowercase")]
109#[non_exhaustive]
110pub enum ReplicaLevel {
111    Off,
112    On,
113}
114
115#[derive(Debug, Clone)]
116#[non_exhaustive]
117pub struct ScanVectorEntry {
118    pub(crate) seq_no: u64,
119    pub(crate) vb_uuid: String,
120}
121
122impl ScanVectorEntry {
123    pub fn new(seq_no: u64, vb_uuid: impl Into<String>) -> Self {
124        Self {
125            seq_no,
126            vb_uuid: vb_uuid.into(),
127        }
128    }
129}
130
131impl Serialize for ScanVectorEntry {
132    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
133    where
134        S: Serializer,
135    {
136        let mut seq = serializer.serialize_seq(Some(2))?;
137        seq.serialize_element(&self.seq_no)?;
138        seq.serialize_element(&self.vb_uuid)?;
139
140        seq.end()
141    }
142}
143
144pub type FullScanVectors = Vec<ScanVectorEntry>;
145pub type SparseScanVectors = HashMap<String, ScanVectorEntry>;
146
147#[derive(Debug, Clone, Default)]
148#[non_exhaustive]
149pub struct QueryOptions {
150    pub(crate) args: Option<Vec<Value>>,
151    pub(crate) atr_collection: Option<String>,
152    pub(crate) auto_execute: Option<bool>,
153    pub(crate) client_context_id: Option<String>,
154    pub(crate) compression: Option<Compression>,
155    pub(crate) controls: Option<bool>,
156    pub(crate) creds: Option<Vec<CredsJson>>,
157    pub(crate) durability_level: Option<DurabilityLevel>,
158    pub(crate) encoded_plan: Option<String>,
159    pub(crate) encoding: Option<Encoding>,
160    pub(crate) format: Option<Format>,
161    pub(crate) kv_timeout: Option<Duration>,
162    pub(crate) max_parallelism: Option<u32>,
163    pub(crate) memory_quota: Option<u32>,
164    pub(crate) metrics: Option<bool>,
165    pub(crate) namespace: Option<String>,
166    pub(crate) num_atrs: Option<u32>,
167    pub(crate) pipeline_batch: Option<u32>,
168    pub(crate) pipeline_cap: Option<u32>,
169    pub(crate) prepared: Option<String>,
170    pub(crate) preserve_expiry: Option<bool>,
171    pub(crate) pretty: Option<bool>,
172    pub(crate) profile: Option<ProfileMode>,
173    pub(crate) query_context: Option<String>,
174    pub(crate) read_only: Option<bool>,
175    pub(crate) scan_cap: Option<u32>,
176    pub(crate) scan_consistency: Option<ScanConsistency>,
177    pub(crate) sparse_scan_vector: Option<SparseScanVectors>,
178    pub(crate) full_scan_vector: Option<FullScanVectors>,
179    pub(crate) sparse_scan_vectors: Option<HashMap<String, SparseScanVectors>>,
180    pub(crate) full_scan_vectors: Option<HashMap<String, FullScanVectors>>,
181    pub(crate) scan_wait: Option<Duration>,
182    pub(crate) signature: Option<bool>,
183    pub(crate) statement: Option<String>,
184    pub(crate) timeout: Option<Duration>,
185    pub(crate) tx_data: Option<Vec<u8>>,
186    pub(crate) tx_id: Option<String>,
187    pub(crate) tx_implicit: Option<bool>,
188    pub(crate) tx_stmt_num: Option<u32>,
189    pub(crate) tx_timeout: Option<Duration>,
190    pub(crate) use_cbo: Option<bool>,
191    pub(crate) use_fts: Option<bool>,
192    pub(crate) use_replica: Option<ReplicaLevel>,
193
194    pub(crate) named_args: Option<HashMap<String, Value>>,
195    pub(crate) raw: Option<HashMap<String, Value>>,
196
197    pub(crate) on_behalf_of: Option<OnBehalfOfInfo>,
198}
199
200impl QueryOptions {
201    pub fn new() -> Self {
202        Default::default()
203    }
204
205    pub fn args(mut self, args: impl Into<Option<Vec<Value>>>) -> Self {
206        self.args = args.into();
207        self
208    }
209
210    pub fn atr_collection(mut self, atr_collection: impl Into<Option<String>>) -> Self {
211        self.atr_collection = atr_collection.into();
212        self
213    }
214
215    pub fn auto_execute(mut self, auto_execute: impl Into<Option<bool>>) -> Self {
216        self.auto_execute = auto_execute.into();
217        self
218    }
219
220    pub fn client_context_id(mut self, client_context_id: impl Into<Option<String>>) -> Self {
221        self.client_context_id = client_context_id.into();
222        self
223    }
224
225    pub fn compression(mut self, compression: impl Into<Option<Compression>>) -> Self {
226        self.compression = compression.into();
227        self
228    }
229
230    pub fn controls(mut self, controls: impl Into<Option<bool>>) -> Self {
231        self.controls = controls.into();
232        self
233    }
234
235    pub fn creds(mut self, creds: impl Into<Option<Vec<CredsJson>>>) -> Self {
236        self.creds = creds.into();
237        self
238    }
239
240    pub fn durability_level(
241        mut self,
242        durability_level: impl Into<Option<DurabilityLevel>>,
243    ) -> Self {
244        self.durability_level = durability_level.into();
245        self
246    }
247
248    pub fn encoded_plan(mut self, encoded_plan: impl Into<Option<String>>) -> Self {
249        self.encoded_plan = encoded_plan.into();
250        self
251    }
252
253    pub fn encoding(mut self, encoding: impl Into<Option<Encoding>>) -> Self {
254        self.encoding = encoding.into();
255        self
256    }
257
258    pub fn format(mut self, format: impl Into<Option<Format>>) -> Self {
259        self.format = format.into();
260        self
261    }
262
263    pub fn kv_timeout(mut self, kv_timeout: impl Into<Option<Duration>>) -> Self {
264        self.kv_timeout = kv_timeout.into();
265        self
266    }
267
268    pub fn max_parallelism(mut self, max_parallelism: impl Into<Option<u32>>) -> Self {
269        self.max_parallelism = max_parallelism.into();
270        self
271    }
272
273    pub fn memory_quota(mut self, memory_quota: impl Into<Option<u32>>) -> Self {
274        self.memory_quota = memory_quota.into();
275        self
276    }
277
278    pub fn metrics(mut self, metrics: impl Into<Option<bool>>) -> Self {
279        self.metrics = metrics.into();
280        self
281    }
282
283    pub fn namespace(mut self, namespace: impl Into<Option<String>>) -> Self {
284        self.namespace = namespace.into();
285        self
286    }
287
288    pub fn num_atrs(mut self, num_atrs: impl Into<Option<u32>>) -> Self {
289        self.num_atrs = num_atrs.into();
290        self
291    }
292
293    pub fn pipeline_batch(mut self, pipeline_batch: impl Into<Option<u32>>) -> Self {
294        self.pipeline_batch = pipeline_batch.into();
295        self
296    }
297
298    pub fn pipeline_cap(mut self, pipeline_cap: impl Into<Option<u32>>) -> Self {
299        self.pipeline_cap = pipeline_cap.into();
300        self
301    }
302
303    pub fn prepared(mut self, prepared: impl Into<Option<String>>) -> Self {
304        self.prepared = prepared.into();
305        self
306    }
307
308    pub fn preserve_expiry(mut self, preserve_expiry: impl Into<Option<bool>>) -> Self {
309        self.preserve_expiry = preserve_expiry.into();
310        self
311    }
312
313    pub fn pretty(mut self, pretty: impl Into<Option<bool>>) -> Self {
314        self.pretty = pretty.into();
315        self
316    }
317
318    pub fn profile(mut self, profile: impl Into<Option<ProfileMode>>) -> Self {
319        self.profile = profile.into();
320        self
321    }
322
323    pub fn query_context(mut self, query_context: impl Into<Option<String>>) -> Self {
324        self.query_context = query_context.into();
325        self
326    }
327
328    pub fn read_only(mut self, read_only: impl Into<Option<bool>>) -> Self {
329        self.read_only = read_only.into();
330        self
331    }
332
333    pub fn scan_cap(mut self, scan_cap: impl Into<Option<u32>>) -> Self {
334        self.scan_cap = scan_cap.into();
335        self
336    }
337
338    pub fn scan_consistency(
339        mut self,
340        scan_consistency: impl Into<Option<ScanConsistency>>,
341    ) -> Self {
342        self.scan_consistency = scan_consistency.into();
343        self
344    }
345
346    pub fn sparse_scan_vector(
347        mut self,
348        sparse_scan_vector: impl Into<Option<SparseScanVectors>>,
349    ) -> Self {
350        self.sparse_scan_vector = sparse_scan_vector.into();
351        self
352    }
353
354    pub fn full_scan_vector(
355        mut self,
356        full_scan_vector: impl Into<Option<FullScanVectors>>,
357    ) -> Self {
358        self.full_scan_vector = full_scan_vector.into();
359        self
360    }
361
362    pub fn sparse_scan_vectors(
363        mut self,
364        sparse_scan_vectors: impl Into<Option<HashMap<String, SparseScanVectors>>>,
365    ) -> Self {
366        self.sparse_scan_vectors = sparse_scan_vectors.into();
367        self
368    }
369
370    pub fn full_scan_vectors(
371        mut self,
372        full_scan_vectors: impl Into<Option<HashMap<String, FullScanVectors>>>,
373    ) -> Self {
374        self.full_scan_vectors = full_scan_vectors.into();
375        self
376    }
377
378    pub fn scan_wait(mut self, scan_wait: impl Into<Option<Duration>>) -> Self {
379        self.scan_wait = scan_wait.into();
380        self
381    }
382
383    pub fn signature(mut self, signature: impl Into<Option<bool>>) -> Self {
384        self.signature = signature.into();
385        self
386    }
387
388    pub fn statement(mut self, statement: impl Into<Option<String>>) -> Self {
389        self.statement = statement.into();
390        self
391    }
392
393    pub fn timeout(mut self, timeout: impl Into<Option<Duration>>) -> Self {
394        self.timeout = timeout.into();
395        self
396    }
397
398    pub fn tx_data(mut self, tx_data: impl Into<Option<Vec<u8>>>) -> Self {
399        self.tx_data = tx_data.into();
400        self
401    }
402
403    pub fn tx_id(mut self, tx_id: impl Into<Option<String>>) -> Self {
404        self.tx_id = tx_id.into();
405        self
406    }
407
408    pub fn tx_implicit(mut self, tx_implicit: impl Into<Option<bool>>) -> Self {
409        self.tx_implicit = tx_implicit.into();
410        self
411    }
412
413    pub fn tx_stmt_num(mut self, tx_stmt_num: impl Into<Option<u32>>) -> Self {
414        self.tx_stmt_num = tx_stmt_num.into();
415        self
416    }
417
418    pub fn tx_timeout(mut self, tx_timeout: impl Into<Option<Duration>>) -> Self {
419        self.tx_timeout = tx_timeout.into();
420        self
421    }
422
423    pub fn use_cbo(mut self, use_cbo: impl Into<Option<bool>>) -> Self {
424        self.use_cbo = use_cbo.into();
425        self
426    }
427
428    pub fn use_fts(mut self, use_fts: impl Into<Option<bool>>) -> Self {
429        self.use_fts = use_fts.into();
430        self
431    }
432
433    pub fn use_replica(mut self, use_replica: impl Into<Option<ReplicaLevel>>) -> Self {
434        self.use_replica = use_replica.into();
435        self
436    }
437
438    pub fn named_args(mut self, named_args: impl Into<Option<HashMap<String, Value>>>) -> Self {
439        self.named_args = named_args.into();
440        self
441    }
442
443    pub fn raw(mut self, raw: impl Into<Option<HashMap<String, Value>>>) -> Self {
444        self.raw = raw.into();
445        self
446    }
447
448    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<OnBehalfOfInfo>>) -> Self {
449        self.on_behalf_of = on_behalf_of.into();
450        self
451    }
452}
453
454impl Serialize for QueryOptions {
455    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
456    where
457        S: Serializer,
458    {
459        use helpers::durations;
460        use serde::ser::SerializeMap;
461        let mut map = serializer.serialize_map(None)?;
462
463        macro_rules! serialize_if_not_none {
464            ($field:expr, $name:expr) => {
465                if !$field.is_none() {
466                    map.serialize_entry($name, &$field)?;
467                }
468            };
469        }
470
471        macro_rules! serialize_duration_if_not_none {
472            ($field:expr, $name:expr) => {
473                if !$field.is_none() {
474                    map.serialize_entry(
475                        $name,
476                        &durations::duration_to_golang_string(&$field.unwrap()),
477                    )?;
478                }
479            };
480        }
481
482        serialize_if_not_none!(self.args, "args");
483        serialize_if_not_none!(self.atr_collection, "atr_collection");
484        serialize_if_not_none!(self.auto_execute, "auto_execute");
485        serialize_if_not_none!(self.client_context_id, "client_context_id");
486        serialize_if_not_none!(self.compression, "compression");
487        serialize_if_not_none!(self.controls, "controls");
488        serialize_if_not_none!(self.creds, "creds");
489        serialize_if_not_none!(self.durability_level, "durability_level");
490        serialize_if_not_none!(self.encoded_plan, "encoded_plan");
491        serialize_if_not_none!(self.encoding, "encoding");
492        serialize_if_not_none!(self.format, "format");
493        serialize_duration_if_not_none!(self.kv_timeout, "kvtimeout");
494        serialize_if_not_none!(self.max_parallelism, "max_parallelism");
495        serialize_if_not_none!(self.memory_quota, "memory_quota");
496        serialize_if_not_none!(self.metrics, "metrics");
497        serialize_if_not_none!(self.namespace, "namespace");
498        serialize_if_not_none!(self.num_atrs, "num_atrs");
499        serialize_if_not_none!(self.pipeline_batch, "pipeline_batch");
500        serialize_if_not_none!(self.pipeline_cap, "pipeline_cap");
501        serialize_if_not_none!(self.prepared, "prepared");
502        serialize_if_not_none!(self.preserve_expiry, "preserve_expiry");
503        serialize_if_not_none!(self.pretty, "pretty");
504        serialize_if_not_none!(self.profile, "profile");
505        serialize_if_not_none!(self.query_context, "query_context");
506        serialize_if_not_none!(self.read_only, "readonly");
507        serialize_if_not_none!(self.scan_cap, "scan_cap");
508        serialize_if_not_none!(self.scan_consistency, "scan_consistency");
509        serialize_if_not_none!(self.sparse_scan_vector, "scan_vector");
510        serialize_if_not_none!(self.full_scan_vector, "scan_vector");
511        serialize_if_not_none!(self.sparse_scan_vectors, "scan_vectors");
512        serialize_if_not_none!(self.full_scan_vectors, "scan_vectors");
513        serialize_duration_if_not_none!(self.scan_wait, "scan_wait");
514        serialize_if_not_none!(self.signature, "signature");
515        serialize_if_not_none!(self.statement, "statement");
516        serialize_duration_if_not_none!(self.timeout, "timeout");
517        serialize_if_not_none!(self.tx_data, "txdata");
518        serialize_if_not_none!(self.tx_id, "txid");
519        serialize_if_not_none!(self.tx_implicit, "tximplicit");
520        serialize_if_not_none!(self.tx_stmt_num, "txstmtnum");
521        serialize_duration_if_not_none!(self.tx_timeout, "txtimeout");
522        serialize_if_not_none!(self.use_cbo, "use_cbo");
523        serialize_if_not_none!(self.use_fts, "use_fts");
524        serialize_if_not_none!(self.use_replica, "use_replica");
525
526        if let Some(args) = &self.named_args {
527            // Prefix each named_arg with "$" if not already prefixed.
528            for (key, value) in args {
529                let key = if key.starts_with('$') {
530                    key
531                } else {
532                    &format!("${key}")
533                };
534                map.serialize_entry(key, value)?;
535            }
536        }
537
538        if let Some(raw) = &self.raw {
539            // Move raw fields to the top level.
540            for (key, value) in raw {
541                map.serialize_entry(key, value)?;
542            }
543        }
544
545        map.end()
546    }
547}
548
549#[derive(Debug, Clone, Default)]
550#[non_exhaustive]
551pub struct GetAllIndexesOptions<'a> {
552    pub(crate) bucket_name: &'a str,
553    pub(crate) scope_name: Option<&'a str>,
554    pub(crate) collection_name: Option<&'a str>,
555    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
556}
557
558impl<'a> GetAllIndexesOptions<'a> {
559    pub fn new() -> Self {
560        Default::default()
561    }
562
563    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
564        self.bucket_name = bucket_name;
565        self
566    }
567
568    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
569        self.scope_name = scope_name.into();
570        self
571    }
572
573    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
574        self.collection_name = collection_name.into();
575        self
576    }
577
578    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
579        self.on_behalf_of = on_behalf_of.into();
580        self
581    }
582}
583
584#[derive(Debug, Clone, Default)]
585#[non_exhaustive]
586pub struct CreatePrimaryIndexOptions<'a> {
587    pub(crate) bucket_name: &'a str,
588    pub(crate) scope_name: Option<&'a str>,
589    pub(crate) collection_name: Option<&'a str>,
590    pub(crate) index_name: Option<&'a str>,
591    pub(crate) num_replicas: Option<u32>,
592    pub(crate) deferred: Option<bool>,
593    pub(crate) ignore_if_exists: Option<bool>,
594    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
595}
596
597impl<'a> CreatePrimaryIndexOptions<'a> {
598    pub fn new() -> Self {
599        Default::default()
600    }
601
602    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
603        self.bucket_name = bucket_name;
604        self
605    }
606
607    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
608        self.scope_name = scope_name.into();
609        self
610    }
611
612    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
613        self.collection_name = collection_name.into();
614        self
615    }
616
617    pub fn index_name(mut self, index_name: impl Into<Option<&'a str>>) -> Self {
618        self.index_name = index_name.into();
619        self
620    }
621
622    pub fn num_replicas(mut self, num_replicas: impl Into<Option<u32>>) -> Self {
623        self.num_replicas = num_replicas.into();
624        self
625    }
626
627    pub fn deferred(mut self, deferred: impl Into<Option<bool>>) -> Self {
628        self.deferred = deferred.into();
629        self
630    }
631
632    pub fn ignore_if_exists(mut self, ignore_if_exists: impl Into<Option<bool>>) -> Self {
633        self.ignore_if_exists = ignore_if_exists.into();
634        self
635    }
636
637    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
638        self.on_behalf_of = on_behalf_of.into();
639        self
640    }
641}
642
643#[derive(Debug, Clone, Default)]
644#[non_exhaustive]
645pub struct CreateIndexOptions<'a> {
646    pub(crate) bucket_name: &'a str,
647    pub(crate) scope_name: Option<&'a str>,
648    pub(crate) collection_name: Option<&'a str>,
649    pub(crate) index_name: &'a str,
650    pub(crate) num_replicas: Option<u32>,
651    pub(crate) fields: &'a [&'a str],
652    pub(crate) deferred: Option<bool>,
653    pub(crate) ignore_if_exists: Option<bool>,
654    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
655}
656
657impl<'a> CreateIndexOptions<'a> {
658    pub fn new() -> Self {
659        Default::default()
660    }
661
662    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
663        self.bucket_name = bucket_name;
664        self
665    }
666
667    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
668        self.scope_name = scope_name.into();
669        self
670    }
671
672    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
673        self.collection_name = collection_name.into();
674        self
675    }
676
677    pub fn index_name(mut self, index_name: &'a str) -> Self {
678        self.index_name = index_name;
679        self
680    }
681
682    pub fn num_replicas(mut self, num_replicas: impl Into<Option<u32>>) -> Self {
683        self.num_replicas = num_replicas.into();
684        self
685    }
686
687    pub fn fields(mut self, fields: &'a [&'a str]) -> Self {
688        self.fields = fields;
689        self
690    }
691
692    pub fn deferred(mut self, deferred: impl Into<Option<bool>>) -> Self {
693        self.deferred = deferred.into();
694        self
695    }
696
697    pub fn ignore_if_exists(mut self, ignore_if_exists: impl Into<Option<bool>>) -> Self {
698        self.ignore_if_exists = ignore_if_exists.into();
699        self
700    }
701
702    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
703        self.on_behalf_of = on_behalf_of.into();
704        self
705    }
706}
707
708#[derive(Debug, Clone, Default)]
709#[non_exhaustive]
710pub struct DropPrimaryIndexOptions<'a> {
711    pub(crate) bucket_name: &'a str,
712    pub(crate) scope_name: Option<&'a str>,
713    pub(crate) collection_name: Option<&'a str>,
714    pub(crate) index_name: Option<&'a str>,
715    pub(crate) ignore_if_not_exists: Option<bool>,
716    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
717}
718
719impl<'a> DropPrimaryIndexOptions<'a> {
720    pub fn new() -> Self {
721        Default::default()
722    }
723
724    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
725        self.bucket_name = bucket_name;
726        self
727    }
728
729    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
730        self.scope_name = scope_name.into();
731        self
732    }
733
734    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
735        self.collection_name = collection_name.into();
736        self
737    }
738
739    pub fn index_name(mut self, index_name: impl Into<Option<&'a str>>) -> Self {
740        self.index_name = index_name.into();
741        self
742    }
743
744    pub fn ignore_if_not_exists(mut self, ignore_if_not_exists: impl Into<Option<bool>>) -> Self {
745        self.ignore_if_not_exists = ignore_if_not_exists.into();
746        self
747    }
748
749    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
750        self.on_behalf_of = on_behalf_of.into();
751        self
752    }
753}
754
755#[derive(Debug, Clone, Default)]
756#[non_exhaustive]
757pub struct DropIndexOptions<'a> {
758    pub(crate) bucket_name: &'a str,
759    pub(crate) scope_name: Option<&'a str>,
760    pub(crate) collection_name: Option<&'a str>,
761    pub(crate) index_name: &'a str,
762    pub(crate) ignore_if_not_exists: Option<bool>,
763    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
764}
765
766impl<'a> DropIndexOptions<'a> {
767    pub fn new() -> Self {
768        Default::default()
769    }
770
771    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
772        self.bucket_name = bucket_name;
773        self
774    }
775
776    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
777        self.scope_name = scope_name.into();
778        self
779    }
780
781    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
782        self.collection_name = collection_name.into();
783        self
784    }
785
786    pub fn index_name(mut self, index_name: &'a str) -> Self {
787        self.index_name = index_name;
788        self
789    }
790
791    pub fn ignore_if_not_exists(mut self, ignore_if_not_exists: impl Into<Option<bool>>) -> Self {
792        self.ignore_if_not_exists = ignore_if_not_exists.into();
793        self
794    }
795
796    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
797        self.on_behalf_of = on_behalf_of.into();
798        self
799    }
800}
801
802#[derive(Debug, Clone, Default)]
803#[non_exhaustive]
804pub struct BuildDeferredIndexesOptions<'a> {
805    pub(crate) bucket_name: &'a str,
806    pub(crate) scope_name: Option<&'a str>,
807    pub(crate) collection_name: Option<&'a str>,
808    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
809}
810
811impl<'a> BuildDeferredIndexesOptions<'a> {
812    pub fn new() -> Self {
813        Default::default()
814    }
815
816    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
817        self.bucket_name = bucket_name;
818        self
819    }
820
821    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
822        self.scope_name = scope_name.into();
823        self
824    }
825
826    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
827        self.collection_name = collection_name.into();
828        self
829    }
830
831    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
832        self.on_behalf_of = on_behalf_of.into();
833        self
834    }
835}
836
837#[derive(Debug, Clone, Default)]
838#[non_exhaustive]
839pub struct WatchIndexesOptions<'a> {
840    pub(crate) bucket_name: &'a str,
841    pub(crate) scope_name: Option<&'a str>,
842    pub(crate) collection_name: Option<&'a str>,
843    pub(crate) indexes: &'a [&'a str],
844    pub(crate) watch_primary: Option<bool>,
845    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
846}
847
848impl<'a> WatchIndexesOptions<'a> {
849    pub fn new() -> Self {
850        Default::default()
851    }
852
853    pub fn bucket_name(mut self, bucket_name: &'a str) -> Self {
854        self.bucket_name = bucket_name;
855        self
856    }
857
858    pub fn scope_name(mut self, scope_name: impl Into<Option<&'a str>>) -> Self {
859        self.scope_name = scope_name.into();
860        self
861    }
862
863    pub fn collection_name(mut self, collection_name: impl Into<Option<&'a str>>) -> Self {
864        self.collection_name = collection_name.into();
865        self
866    }
867
868    pub fn indexes(mut self, indexes: &'a [&'a str]) -> Self {
869        self.indexes = indexes;
870        self
871    }
872
873    pub fn watch_primary(mut self, watch_primary: impl Into<Option<bool>>) -> Self {
874        self.watch_primary = watch_primary.into();
875        self
876    }
877
878    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
879        self.on_behalf_of = on_behalf_of.into();
880        self
881    }
882}
883
884#[derive(Debug, Clone, Eq, PartialEq)]
885pub struct EnsureIndexPollOptions<C: Client> {
886    pub desired_state: DesiredState,
887    pub client: Arc<C>,
888    pub targets: Vec<NodeTarget>,
889}
890
891#[derive(Debug, Clone, Default)]
892#[non_exhaustive]
893pub struct PingOptions<'a> {
894    pub(crate) on_behalf_of: Option<&'a OnBehalfOfInfo>,
895}
896
897impl<'a> PingOptions<'a> {
898    pub fn new() -> Self {
899        Default::default()
900    }
901
902    pub fn on_behalf_of(mut self, on_behalf_of: impl Into<Option<&'a OnBehalfOfInfo>>) -> Self {
903        self.on_behalf_of = on_behalf_of.into();
904        self
905    }
906}