firestore_structured_query/
query.rs

1use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
2    structured_query, Cursor, StructuredQuery,
3};
4
5/// A Firestore query.
6///
7/// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#structuredquery>
8///
9/// # Examples
10///
11/// ```rust
12/// # fn example_mod_doc() -> firestore_structured_query::Result<()> {
13/// use firestore_structured_query::{FieldPath, Filter, Query};
14/// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
15///     structured_query, value::ValueType, ArrayValue, Cursor, StructuredQuery, Value,
16/// };
17///
18/// let _ = StructuredQuery::from(
19///     // or Query::collection_group(...)
20///     Query::collection("collection_id1")
21///         .select([FieldPath::raw("field1"), FieldPath::raw("field2")])
22///         .r#where(Filter::and([
23///             // field filters
24///             FieldPath::raw("field1").less_than(Value { value_type: Some(ValueType::IntegerValue(1)) })?,
25///             FieldPath::raw("field2").less_than_or_equal(Value { value_type: Some(ValueType::IntegerValue(2)) })?,
26///             FieldPath::raw("field3").greater_than(Value { value_type: Some(ValueType::IntegerValue(3)) })?,
27///             FieldPath::raw("field4").greater_than_or_equal(Value { value_type: Some(ValueType::IntegerValue(4)) })?,
28///             FieldPath::raw("field5").equal(Value { value_type: Some(ValueType::IntegerValue(5)) })?,
29///             FieldPath::raw("field6").not_equal(Value { value_type: Some(ValueType::IntegerValue(6)) })?,
30///             FieldPath::raw("field7").array_contains(Value { value_type: Some(ValueType::IntegerValue(7)) })?,
31///             FieldPath::raw("field8").r#in(Value { value_type: Some(ValueType::ArrayValue(ArrayValue { values: vec![Value { value_type: Some(ValueType::IntegerValue(8)) }] })) })?,
32///             FieldPath::raw("field9").array_contains_any(Value { value_type: Some(ValueType::ArrayValue(ArrayValue { values: vec![Value { value_type: Some(ValueType::IntegerValue(9)) }] })) })?,
33///             FieldPath::raw("field10").not_in(Value { value_type: Some(ValueType::ArrayValue(ArrayValue { values: vec![Value { value_type: Some(ValueType::IntegerValue(10)) }] })) })?,
34///             // unary filters
35///             FieldPath::raw("field11").is_nan()?,
36///             FieldPath::raw("field12").is_not_nan()?,
37///             FieldPath::raw("field13").is_not_null()?,
38///             FieldPath::raw("field14").is_null()?,
39///             // composite filters
40///             Filter::and([
41///                 FieldPath::raw("f").equal(Value { value_type: Some(ValueType::StringValue("a".to_string())) })?,
42///                 FieldPath::raw("f").equal(Value { value_type: Some(ValueType::StringValue("b".to_string())) })?,
43///             ]),
44///             Filter::or([
45///                 FieldPath::raw("f").equal(Value { value_type: Some(ValueType::StringValue("a".to_string())) })?,
46///                 FieldPath::raw("f").equal(Value { value_type: Some(ValueType::StringValue("b".to_string())) })?,
47///             ]),
48///         ]))
49///         .order_by([
50///             FieldPath::raw("field1").ascending(),
51///             FieldPath::raw("field2").descending(),
52///         ])
53///         // .start_after(...)
54///         .start_at([
55///             Value { value_type: Some(ValueType::IntegerValue(1))},
56///             Value { value_type: Some(ValueType::IntegerValue(2))},
57///         ])
58///         // .end_before(...)
59///         .end_at([
60///             Value { value_type: Some(ValueType::IntegerValue(1))},
61///             Value { value_type: Some(ValueType::IntegerValue(2))},
62///         ])
63///         .offset(1_i32)
64///         .limit(2_i32),
65/// );
66/// #     Ok(())
67/// # }
68/// ```
69#[derive(Clone, Debug, PartialEq)]
70pub struct Query(StructuredQuery);
71
72impl Query {
73    /// Creates a new `Query` for a collection.
74    ///
75    /// The query that internally holds a `CollectionSelector` with `all_descendants` set to `false`.
76    ///
77    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.CollectionSelector>
78    ///
79    /// # Examples
80    ///
81    /// ```rust
82    /// # fn test_query_collection() -> firestore_structured_query::Result<()> {
83    /// use firestore_structured_query::Query;
84    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
85    /// let query1 = Query::collection("collection_id1");
86    /// assert_eq!(
87    ///     StructuredQuery::from(query1),
88    ///     StructuredQuery {
89    ///         select: None,
90    ///         from: vec![structured_query::CollectionSelector {
91    ///             collection_id: "collection_id1".to_string(),
92    ///             all_descendants: false,
93    ///         }],
94    ///         r#where: None,
95    ///         order_by: vec![],
96    ///         start_at: None,
97    ///         end_at: None,
98    ///         offset: 0_i32,
99    ///         limit: None,
100    ///         find_nearest: None,
101    ///     }
102    /// );
103    /// #     Ok(())
104    /// # }
105    /// ```
106    pub fn collection<S>(collection_id: S) -> Self
107    where
108        S: Into<String>,
109    {
110        Self(StructuredQuery {
111            select: None,
112            from: vec![structured_query::CollectionSelector {
113                collection_id: collection_id.into(),
114                all_descendants: false,
115            }],
116            r#where: None,
117            order_by: vec![],
118            start_at: None,
119            end_at: None,
120            offset: 0_i32,
121            limit: None,
122            find_nearest: None,
123        })
124    }
125
126    /// Creates a new `Query` for a collection group.
127    ///
128    /// The query that internally holds a `CollectionSelector` with `all_descendants` set to `true`.
129    ///
130    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.CollectionSelector>
131    ///
132    /// # Examples
133    ///
134    /// ```rust
135    /// # fn test_query_collection_group() -> firestore_structured_query::Result<()> {
136    /// use firestore_structured_query::Query;
137    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
138    /// let query1 = Query::collection_group("collection_id1");
139    /// assert_eq!(
140    ///     StructuredQuery::from(query1),
141    ///     StructuredQuery {
142    ///         select: None,
143    ///         from: vec![structured_query::CollectionSelector {
144    ///             collection_id: "collection_id1".to_string(),
145    ///             all_descendants: true,
146    ///         }],
147    ///         r#where: None,
148    ///         order_by: vec![],
149    ///         start_at: None,
150    ///         end_at: None,
151    ///         offset: 0_i32,
152    ///         limit: None,
153    ///         find_nearest: None,
154    ///     }
155    /// );
156    /// #     Ok(())
157    /// # }
158    /// ```
159    pub fn collection_group<S>(collection_id: S) -> Self
160    where
161        S: Into<String>,
162    {
163        Self(StructuredQuery {
164            select: None,
165            from: vec![structured_query::CollectionSelector {
166                collection_id: collection_id.into(),
167                all_descendants: true,
168            }],
169            r#where: None,
170            order_by: vec![],
171            start_at: None,
172            end_at: None,
173            offset: 0_i32,
174            limit: None,
175            find_nearest: None,
176        })
177    }
178
179    /// Sets the specified value to end_at and returns the Query.
180    ///
181    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.Cursor.google.firestore.v1.StructuredQuery.end_at>
182    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.Cursor>
183    ///
184    /// # Examples
185    ///
186    /// ```rust
187    /// # fn test_query_end_at() -> firestore_structured_query::Result<()> {
188    /// use firestore_structured_query::Query;
189    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
190    ///     structured_query, value::ValueType, Cursor, StructuredQuery, Value,
191    /// };
192    /// let query1 = Query::collection_group("collection_id1").end_at([
193    ///     Value {
194    ///         value_type: Some(ValueType::IntegerValue(1)),
195    ///     },
196    ///     Value {
197    ///         value_type: Some(ValueType::IntegerValue(2)),
198    ///     },
199    /// ]);
200    /// assert_eq!(
201    ///     StructuredQuery::from(query1),
202    ///     StructuredQuery {
203    ///         select: None,
204    ///         from: vec![structured_query::CollectionSelector {
205    ///             collection_id: "collection_id1".to_string(),
206    ///             all_descendants: true,
207    ///         }],
208    ///         r#where: None,
209    ///         order_by: vec![],
210    ///         start_at: None,
211    ///         end_at: Some(Cursor {
212    ///             values: vec![
213    ///                 Value {
214    ///                     value_type: Some(ValueType::IntegerValue(1)),
215    ///                 },
216    ///                 Value {
217    ///                     value_type: Some(ValueType::IntegerValue(2)),
218    ///                 },
219    ///             ],
220    ///             before: false,
221    ///         }),
222    ///         offset: 0_i32,
223    ///         limit: None,
224    ///         find_nearest: None,
225    ///     }
226    /// );
227    /// #     Ok(())
228    /// # }
229    /// ```
230    pub fn end_at<I>(mut self, values: I) -> Self
231    where
232        I: IntoIterator<Item = googleapis_tonic_google_firestore_v1::google::firestore::v1::Value>,
233    {
234        self.0.end_at = Some(Cursor {
235            values: values.into_iter().collect(),
236            before: false,
237        });
238        self
239    }
240
241    /// Sets the specified value to end_at and returns the Query.
242    ///
243    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.Cursor.google.firestore.v1.StructuredQuery.end_at>
244    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.Cursor>
245    ///
246    /// # Examples
247    ///
248    /// ```rust
249    /// # fn test_query_end_before() -> firestore_structured_query::Result<()> {
250    /// use firestore_structured_query::Query;
251    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
252    ///     structured_query, value::ValueType, Cursor, StructuredQuery, Value,
253    /// };
254    /// let query1 = Query::collection_group("collection_id1").end_before([
255    ///     Value {
256    ///         value_type: Some(ValueType::IntegerValue(1)),
257    ///     },
258    ///     Value {
259    ///         value_type: Some(ValueType::IntegerValue(2)),
260    ///     },
261    /// ]);
262    /// assert_eq!(
263    ///     StructuredQuery::from(query1),
264    ///     StructuredQuery {
265    ///         select: None,
266    ///         from: vec![structured_query::CollectionSelector {
267    ///             collection_id: "collection_id1".to_string(),
268    ///             all_descendants: true,
269    ///         }],
270    ///         r#where: None,
271    ///         order_by: vec![],
272    ///         start_at: None,
273    ///         end_at: Some(Cursor {
274    ///             values: vec![
275    ///                 Value {
276    ///                     value_type: Some(ValueType::IntegerValue(1)),
277    ///                 },
278    ///                 Value {
279    ///                     value_type: Some(ValueType::IntegerValue(2)),
280    ///                 },
281    ///             ],
282    ///             before: true,
283    ///         }),
284    ///         offset: 0_i32,
285    ///         limit: None,
286    ///         find_nearest: None,
287    ///     }
288    /// );
289    /// #     Ok(())
290    /// # }
291    /// ```
292    pub fn end_before<I>(mut self, values: I) -> Self
293    where
294        I: IntoIterator<Item = googleapis_tonic_google_firestore_v1::google::firestore::v1::Value>,
295    {
296        self.0.end_at = Some(Cursor {
297            values: values.into_iter().collect(),
298            before: true,
299        });
300        self
301    }
302
303    /// Sets the specified value to limit and returns the Query.
304    ///
305    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.protobuf.Int32Value.google.firestore.v1.StructuredQuery.limit>
306    ///
307    /// # Examples
308    ///
309    /// ```rust
310    /// # fn test_query_limit() -> firestore_structured_query::Result<()> {
311    /// use firestore_structured_query::Query;
312    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
313    /// let query1 = Query::collection_group("collection_id1").limit(1_i32);
314    /// assert_eq!(
315    ///     StructuredQuery::from(query1),
316    ///     StructuredQuery {
317    ///         select: None,
318    ///         from: vec![structured_query::CollectionSelector {
319    ///             collection_id: "collection_id1".to_string(),
320    ///             all_descendants: true,
321    ///         }],
322    ///         r#where: None,
323    ///         order_by: vec![],
324    ///         start_at: None,
325    ///         end_at: None,
326    ///         offset: 0_i32,
327    ///         limit: Some(1_i32),
328    ///         find_nearest: None,
329    ///     }
330    /// );
331    /// #     Ok(())
332    /// # }
333    /// ```
334    pub fn limit(mut self, limit: i32) -> Self {
335        self.0.limit = Some(limit);
336        self
337    }
338
339    /// Sets the specified value to offset and returns the Query.
340    ///
341    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.int32.google.firestore.v1.StructuredQuery.offset>
342    ///
343    /// # Examples
344    ///
345    /// ```rust
346    /// # fn test_query_offset() -> firestore_structured_query::Result<()> {
347    /// use firestore_structured_query::Query;
348    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
349    /// let query1 = Query::collection_group("collection_id1").offset(1_i32);
350    /// assert_eq!(
351    ///     StructuredQuery::from(query1),
352    ///     StructuredQuery {
353    ///         select: None,
354    ///         from: vec![structured_query::CollectionSelector {
355    ///             collection_id: "collection_id1".to_string(),
356    ///             all_descendants: true,
357    ///         }],
358    ///         r#where: None,
359    ///         order_by: vec![],
360    ///         start_at: None,
361    ///         end_at: None,
362    ///         offset: 1_i32,
363    ///         limit: None,
364    ///         find_nearest: None,
365    ///     }
366    /// );
367    /// #     Ok(())
368    /// # }
369    /// ```
370    pub fn offset(mut self, offset: i32) -> Self {
371        self.0.offset = offset;
372        self
373    }
374
375    /// Sets the specified value to order_by and returns the Query.
376    ///
377    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.repeated.google.firestore.v1.StructuredQuery.Order.google.firestore.v1.StructuredQuery.order_by>
378    ///
379    /// # Examples
380    ///
381    /// ```rust
382    /// # fn test_query_order_by() -> firestore_structured_query::Result<()> {
383    /// use firestore_structured_query::{FieldPath, Query};
384    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
385    /// let query1 = Query::collection_group("collection_id1").order_by([
386    ///     FieldPath::raw("field1").ascending(),
387    ///     FieldPath::raw("field2").descending(),
388    /// ]);
389    /// assert_eq!(
390    ///     StructuredQuery::from(query1),
391    ///     StructuredQuery {
392    ///         select: None,
393    ///         from: vec![structured_query::CollectionSelector {
394    ///             collection_id: "collection_id1".to_string(),
395    ///             all_descendants: true,
396    ///         }],
397    ///         r#where: None,
398    ///         order_by: vec![
399    ///             structured_query::Order::from(FieldPath::raw("field1").ascending()),
400    ///             structured_query::Order::from(FieldPath::raw("field2").descending()),
401    ///         ],
402    ///         start_at: None,
403    ///         end_at: None,
404    ///         offset: 0_i32,
405    ///         limit: None,
406    ///         find_nearest: None,
407    ///     }
408    /// );
409    /// let order_by1 = vec![
410    ///     structured_query::Order {
411    ///         field: Some(structured_query::FieldReference {
412    ///             field_path: "field1".to_string(),
413    ///         }),
414    ///         direction: structured_query::Direction::Ascending as i32,
415    ///     },
416    ///     structured_query::Order {
417    ///         field: Some(structured_query::FieldReference {
418    ///             field_path: "field2".to_string(),
419    ///         }),
420    ///         direction: structured_query::Direction::Descending as i32,
421    ///     },
422    /// ];
423    /// let query2 = Query::collection_group("collection_id1").order_by(order_by1.clone());
424    /// assert_eq!(
425    ///     StructuredQuery::from(query2),
426    ///     StructuredQuery {
427    ///         select: None,
428    ///         from: vec![structured_query::CollectionSelector {
429    ///             collection_id: "collection_id1".to_string(),
430    ///             all_descendants: true,
431    ///         }],
432    ///         r#where: None,
433    ///         order_by: order_by1,
434    ///         start_at: None,
435    ///         end_at: None,
436    ///         offset: 0_i32,
437    ///         limit: None,
438    ///         find_nearest: None,
439    ///     }
440    /// );
441    /// #     Ok(())
442    /// # }
443    /// ```
444    pub fn order_by<I>(mut self, order_by: I) -> Self
445    where
446        I: IntoIterator,
447        I::Item: Into<structured_query::Order>,
448    {
449        self.0.order_by = order_by.into_iter().map(Into::into).collect();
450        self
451    }
452
453    /// Sets the specified value to select and returns the Query.
454    ///
455    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.StructuredQuery.Projection.google.firestore.v1.StructuredQuery.select>
456    ///
457    /// # Examples
458    ///
459    /// ```rust
460    /// # fn test_query_select() -> firestore_structured_query::Result<()> {
461    /// use firestore_structured_query::{FieldPath, Query};
462    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
463    /// let query1 = Query::collection_group("collection_id1")
464    ///     .select([FieldPath::raw("field1"), FieldPath::raw("field2")]);
465    /// assert_eq!(
466    ///     StructuredQuery::from(query1),
467    ///     StructuredQuery {
468    ///         select: Some(structured_query::Projection {
469    ///             fields: vec![
470    ///                 structured_query::FieldReference {
471    ///                     field_path: "field1".to_string(),
472    ///                 },
473    ///                 structured_query::FieldReference {
474    ///                     field_path: "field2".to_string(),
475    ///                 },
476    ///             ],
477    ///         }),
478    ///         from: vec![structured_query::CollectionSelector {
479    ///             collection_id: "collection_id1".to_string(),
480    ///             all_descendants: true,
481    ///         }],
482    ///         r#where: None,
483    ///         order_by: vec![],
484    ///         start_at: None,
485    ///         end_at: None,
486    ///         offset: 0_i32,
487    ///         limit: None,
488    ///         find_nearest: None,
489    ///     }
490    /// );
491    /// #     Ok(())
492    /// # }
493    /// ```
494    pub fn select<I>(mut self, fields: I) -> Self
495    where
496        I: IntoIterator,
497        I::Item: Into<structured_query::FieldReference>,
498    {
499        self.0.select = Some(structured_query::Projection {
500            fields: fields.into_iter().map(Into::into).collect(),
501        });
502        self
503    }
504
505    /// Sets the specified value to start_at and returns the Query.
506    ///
507    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.Cursor.google.firestore.v1.StructuredQuery.start_at>
508    ///
509    /// # Examples
510    ///
511    /// ```rust
512    /// # fn test_query_start_after() -> firestore_structured_query::Result<()> {
513    /// use firestore_structured_query::Query;
514    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
515    ///     structured_query, value::ValueType, Cursor, StructuredQuery, Value,
516    /// };
517    /// let query1 = Query::collection_group("collection_id1").start_after([
518    ///     Value {
519    ///         value_type: Some(ValueType::IntegerValue(1)),
520    ///     },
521    ///     Value {
522    ///         value_type: Some(ValueType::IntegerValue(2)),
523    ///     },
524    /// ]);
525    /// assert_eq!(
526    ///     StructuredQuery::from(query1),
527    ///     StructuredQuery {
528    ///         select: None,
529    ///         from: vec![structured_query::CollectionSelector {
530    ///             collection_id: "collection_id1".to_string(),
531    ///             all_descendants: true,
532    ///         }],
533    ///         r#where: None,
534    ///         order_by: vec![],
535    ///         start_at: Some(Cursor {
536    ///             values: vec![
537    ///                 Value {
538    ///                     value_type: Some(ValueType::IntegerValue(1)),
539    ///                 },
540    ///                 Value {
541    ///                     value_type: Some(ValueType::IntegerValue(2)),
542    ///                 },
543    ///             ],
544    ///             before: false,
545    ///         }),
546    ///         end_at: None,
547    ///         offset: 0_i32,
548    ///         limit: None,
549    ///         find_nearest: None,
550    ///     }
551    /// );
552    /// #     Ok(())
553    /// # }
554    /// ```
555    pub fn start_after<I>(mut self, values: I) -> Self
556    where
557        I: IntoIterator<Item = googleapis_tonic_google_firestore_v1::google::firestore::v1::Value>,
558    {
559        self.0.start_at = Some(Cursor {
560            values: values.into_iter().collect(),
561            before: false,
562        });
563        self
564    }
565
566    /// Sets the specified value to start_at and returns the Query.
567    ///
568    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.Cursor.google.firestore.v1.StructuredQuery.start_at>
569    ///
570    /// # Examples
571    ///
572    /// ```rust
573    /// # fn test_query_start_at() -> firestore_structured_query::Result<()> {
574    /// use firestore_structured_query::Query;
575    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
576    ///     structured_query, value::ValueType, Cursor, StructuredQuery, Value,
577    /// };
578    /// let query1 = Query::collection_group("collection_id1").start_at([
579    ///     Value {
580    ///         value_type: Some(ValueType::IntegerValue(1)),
581    ///     },
582    ///     Value {
583    ///         value_type: Some(ValueType::IntegerValue(2)),
584    ///     },
585    /// ]);
586    /// assert_eq!(
587    ///     StructuredQuery::from(query1),
588    ///     StructuredQuery {
589    ///         select: None,
590    ///         from: vec![structured_query::CollectionSelector {
591    ///             collection_id: "collection_id1".to_string(),
592    ///             all_descendants: true,
593    ///         }],
594    ///         r#where: None,
595    ///         order_by: vec![],
596    ///         start_at: Some(Cursor {
597    ///             values: vec![
598    ///                 Value {
599    ///                     value_type: Some(ValueType::IntegerValue(1)),
600    ///                 },
601    ///                 Value {
602    ///                     value_type: Some(ValueType::IntegerValue(2)),
603    ///                 },
604    ///             ],
605    ///             before: true,
606    ///         }),
607    ///         end_at: None,
608    ///         offset: 0_i32,
609    ///         limit: None,
610    ///         find_nearest: None,
611    ///     }
612    /// );
613    /// #     Ok(())
614    /// # }
615    /// ```
616    pub fn start_at<I>(mut self, values: I) -> Self
617    where
618        I: IntoIterator<Item = googleapis_tonic_google_firestore_v1::google::firestore::v1::Value>,
619    {
620        self.0.start_at = Some(Cursor {
621            values: values.into_iter().collect(),
622            before: true,
623        });
624        self
625    }
626
627    /// Sets the specified value to where and returns the Query.
628    ///
629    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FIELDS.google.firestore.v1.StructuredQuery.Filter.google.firestore.v1.StructuredQuery.where>
630    ///
631    /// # Examples
632    ///
633    /// ```rust
634    /// # fn test_query_where() -> firestore_structured_query::Result<()> {
635    /// use firestore_structured_query::{FieldPath, Query};
636    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, StructuredQuery};
637    /// let query1 =
638    ///     Query::collection_group("collection_id1").r#where(FieldPath::raw("field1").is_nan()?);
639    /// assert_eq!(
640    ///     StructuredQuery::from(query1),
641    ///     StructuredQuery {
642    ///         select: None,
643    ///         from: vec![structured_query::CollectionSelector {
644    ///             collection_id: "collection_id1".to_string(),
645    ///             all_descendants: true,
646    ///         }],
647    ///         r#where: Some(structured_query::Filter {
648    ///             filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
649    ///                 structured_query::UnaryFilter {
650    ///                     op: structured_query::unary_filter::Operator::IsNan as i32,
651    ///                     operand_type: Some(structured_query::unary_filter::OperandType::Field(
652    ///                         structured_query::FieldReference {
653    ///                             field_path: "field1".to_string(),
654    ///                         }
655    ///                     ))
656    ///                 }
657    ///             ))
658    ///         }),
659    ///         order_by: vec![],
660    ///         start_at: None,
661    ///         end_at: None,
662    ///         offset: 0_i32,
663    ///         limit: None,
664    ///         find_nearest: None,
665    ///     }
666    /// );
667    /// let filter1 = structured_query::Filter {
668    ///     filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
669    ///         structured_query::UnaryFilter {
670    ///             op: structured_query::unary_filter::Operator::IsNan as i32,
671    ///             operand_type: Some(structured_query::unary_filter::OperandType::Field(
672    ///                 structured_query::FieldReference {
673    ///                     field_path: "field1".to_string(),
674    ///                 },
675    ///             )),
676    ///         },
677    ///     )),
678    /// };
679    /// let query2 = Query::collection_group("collection_id1").r#where(filter1.clone());
680    /// assert_eq!(
681    ///     StructuredQuery::from(query2),
682    ///     StructuredQuery {
683    ///         select: None,
684    ///         from: vec![structured_query::CollectionSelector {
685    ///             collection_id: "collection_id1".to_string(),
686    ///             all_descendants: true,
687    ///         }],
688    ///         r#where: Some(filter1),
689    ///         order_by: vec![],
690    ///         start_at: None,
691    ///         end_at: None,
692    ///         offset: 0_i32,
693    ///         limit: None,
694    ///         find_nearest: None,
695    ///     }
696    /// );
697    /// #     Ok(())
698    /// # }
699    /// ```
700    pub fn r#where<F>(mut self, filter: F) -> Self
701    where
702        F: Into<structured_query::Filter>,
703    {
704        self.0.r#where = Some(filter.into());
705        self
706    }
707}
708
709impl std::convert::From<Query> for StructuredQuery {
710    fn from(query: Query) -> Self {
711        query.0
712    }
713}