firestore_structured_query/
field_path.rs

1use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query::{
2    self, field_filter, unary_filter,
3};
4
5use crate::error::Result;
6use crate::{Filter, IntoValue, Order};
7
8/// A Firestore Field Path.
9///
10/// <https://firebase.google.com/docs/firestore/quotas#collections_documents_and_fields>
11///
12/// > - Must separate field names with a single period (`.`)
13/// > - May be passed as a dot-delimited (`.`) string of segments where each segment is either a simple field name or a quoted field name (defined below).
14/// >
15/// > A simple field name is one where all of the following are true:
16/// >
17/// > - Contains only the characters `a-z`, `A-Z`, `0-9`, and underscore (`_`)
18/// > - Does not start with `0-9`
19/// >
20/// > A quoted field name starts and ends with the backtick character (`` ` ``). For example, `` foo.`x&y` `` refers to the `x&y` field nested under the `foo` field. To construct a field name with the backtick character, escape the backtick character with the backslash character (`\`). For convenience, you can avoid quoted field names by passing the field path as a FieldPath object (for example, see JavaScript FieldPath).
21///
22/// # Examples
23///
24/// ```rust
25/// use firestore_structured_query::FieldPath;
26/// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
27///
28/// let field_path1 = FieldPath::raw("field1");
29/// assert_eq!(
30///     structured_query::FieldReference::from(field_path1),
31///     structured_query::FieldReference {
32///         field_path: "field1".to_string(),
33///     }
34/// );
35/// ```
36#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
37pub struct FieldPath(String);
38
39fn is_simple_field_name(s: &str) -> bool {
40    s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
41        && !s.starts_with(|c: char| -> bool { c.is_ascii_digit() })
42}
43
44impl FieldPath {
45    /// Creates a new field path.
46    ///
47    /// # Examples
48    ///
49    /// ```rust
50    /// # fn test_field_path_new() {
51    /// use firestore_structured_query::FieldPath;
52    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
53    ///
54    /// // simple field name
55    /// let field_path1 = FieldPath::new(["field1"]);
56    /// assert_eq!(
57    ///     structured_query::FieldReference::from(field_path1),
58    ///     structured_query::FieldReference {
59    ///         field_path: "field1".to_string(),
60    ///     }
61    /// );
62    /// let field_path2 = FieldPath::new(["field1", "field2"]);
63    /// assert_eq!(
64    ///     structured_query::FieldReference::from(field_path2),
65    ///     structured_query::FieldReference {
66    ///         field_path: "field1.field2".to_string(),
67    ///     }
68    /// );
69    /// let field_path3 = FieldPath::new(["foo", "x&y"]);
70    /// assert_eq!(
71    ///     structured_query::FieldReference::from(field_path3),
72    ///     structured_query::FieldReference {
73    ///         field_path: "foo.`x&y`".to_string(),
74    ///     }
75    /// );
76    /// let field_path4 = FieldPath::new(["a`b", r#"a\b"#]);
77    /// assert_eq!(
78    ///     structured_query::FieldReference::from(field_path4),
79    ///     structured_query::FieldReference {
80    ///         field_path: r#"`a\`b`.`a\\b`"#.to_string(),
81    ///     }
82    /// );
83    /// # }
84    /// ```
85    pub fn new<I>(field_names: I) -> Self
86    where
87        I: IntoIterator,
88        I::Item: Into<String>,
89    {
90        Self(
91            field_names
92                .into_iter()
93                .map(Into::into)
94                .map(|s| {
95                    if is_simple_field_name(&s) {
96                        s
97                    } else {
98                        format!("`{}`", s.replace('\\', r#"\\"#).replace('`', r#"\`"#))
99                    }
100                })
101                .collect::<Vec<String>>()
102                .join("."),
103        )
104    }
105
106    /// Creates a new field path without escaping.
107    ///
108    /// # Examples
109    ///
110    /// ```rust
111    /// use firestore_structured_query::FieldPath;
112    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
113    ///
114    /// let field_path1 = FieldPath::raw("field1");
115    /// assert_eq!(
116    ///     structured_query::FieldReference::from(field_path1),
117    ///     structured_query::FieldReference {
118    ///         field_path: "field1".to_string(),
119    ///     }
120    /// );
121    /// ```
122    pub fn raw<S>(field_path: S) -> Self
123    where
124        S: Into<String>,
125    {
126        Self(field_path.into())
127    }
128}
129
130// for Filter
131impl FieldPath {
132    /// Creates a new `FieldFilter` with the `ArrayContains` operator.
133    ///
134    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
135    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.ARRAY_CONTAINS>
136    ///
137    /// # Examples
138    ///
139    /// ```rust
140    /// # #[test]
141    /// # fn test_field_path_array_contains() -> firestore_structured_query::Result<()> {
142    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
143    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
144    /// struct S(i64);
145    /// impl IntoValue for S {
146    ///     fn into_value(self) -> Result<Value> {
147    ///         Ok(Value {
148    ///             value_type: Some(ValueType::IntegerValue(self.0)),
149    ///         })
150    ///     }
151    /// }
152    /// let filter1 = FieldPath::raw("field7").array_contains(Value {
153    ///     value_type: Some(ValueType::IntegerValue(7)),
154    /// })?;
155    /// let filter2 = FieldPath::raw("field7").array_contains(S(7))?;
156    /// let expected = structured_query::Filter {
157    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
158    ///         structured_query::FieldFilter {
159    ///             field: Some(structured_query::FieldReference {
160    ///                 field_path: "field7".to_string(),
161    ///             }),
162    ///             op: structured_query::field_filter::Operator::ArrayContains as i32,
163    ///             value: Some(Value {
164    ///                 value_type: Some(ValueType::IntegerValue(7)),
165    ///             }),
166    ///         },
167    ///     )),
168    /// };
169    /// assert_eq!(structured_query::Filter::from(filter1), expected);
170    /// assert_eq!(structured_query::Filter::from(filter2), expected);
171    /// #     Ok(())
172    /// # }
173    /// ```
174    pub fn array_contains<T>(&self, value: T) -> Result<Filter>
175    where
176        T: IntoValue,
177    {
178        Filter::field(self.clone(), field_filter::Operator::ArrayContains, value)
179    }
180
181    /// Creates a new `FieldFilter` with the `ArrayContainsAny` operator.
182    ///
183    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
184    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.ARRAY_CONTAINS_ANY>
185    ///
186    /// # Examples
187    ///
188    /// ```rust
189    /// # fn test_field_path_array_contains_any() -> firestore_structured_query::Result<()> {
190    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
191    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
192    ///     structured_query, value::ValueType, ArrayValue, Value,
193    /// };
194    /// struct S(Vec<i64>);
195    /// impl IntoValue for S {
196    ///     fn into_value(self) -> Result<Value> {
197    ///         Ok(Value {
198    ///             value_type: Some(ValueType::ArrayValue(ArrayValue {
199    ///                 values: self
200    ///                     .0
201    ///                     .into_iter()
202    ///                     .map(|i| Value {
203    ///                         value_type: Some(ValueType::IntegerValue(i)),
204    ///                     })
205    ///                     .collect(),
206    ///             })),
207    ///         })
208    ///     }
209    /// }
210    /// let filter1 = FieldPath::raw("field9").array_contains_any(Value {
211    ///     value_type: Some(ValueType::ArrayValue(ArrayValue {
212    ///         values: vec![Value {
213    ///             value_type: Some(ValueType::IntegerValue(9)),
214    ///         }],
215    ///     })),
216    /// })?;
217    /// let filter2 = FieldPath::raw("field9").array_contains_any(S(vec![9]))?;
218    /// let expected = structured_query::Filter {
219    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
220    ///         structured_query::FieldFilter {
221    ///             field: Some(structured_query::FieldReference {
222    ///                 field_path: "field9".to_string(),
223    ///             }),
224    ///             op: structured_query::field_filter::Operator::ArrayContainsAny as i32,
225    ///             value: Some(Value {
226    ///                 value_type: Some(ValueType::ArrayValue(ArrayValue {
227    ///                     values: vec![Value {
228    ///                         value_type: Some(ValueType::IntegerValue(9)),
229    ///                     }],
230    ///                 })),
231    ///             }),
232    ///         },
233    ///     )),
234    /// };
235    /// assert_eq!(structured_query::Filter::from(filter1), expected);
236    /// assert_eq!(structured_query::Filter::from(filter2), expected);
237    /// #     Ok(())
238    /// # }
239    /// ```
240    pub fn array_contains_any<T>(&self, value: T) -> Result<Filter>
241    where
242        T: IntoValue,
243    {
244        Filter::field(
245            self.clone(),
246            field_filter::Operator::ArrayContainsAny,
247            value,
248        )
249    }
250
251    /// Creates a new `FieldFilter` with the `Equal` operator.
252    ///
253    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
254    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.EQUAL>
255    ///
256    /// # Examples
257    ///
258    /// ```rust
259    /// # fn test_field_path_equal() -> firestore_structured_query::Result<()> {
260    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
261    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
262    /// struct S(i64);
263    /// impl IntoValue for S {
264    ///     fn into_value(self) -> Result<Value> {
265    ///         Ok(Value {
266    ///             value_type: Some(ValueType::IntegerValue(self.0)),
267    ///         })
268    ///     }
269    /// }
270    /// let filter1 = FieldPath::raw("field5").equal(Value {
271    ///     value_type: Some(ValueType::IntegerValue(5)),
272    /// })?;
273    /// let filter2 = FieldPath::raw("field5").equal(S(5))?;
274    /// let expected = structured_query::Filter {
275    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
276    ///         structured_query::FieldFilter {
277    ///             field: Some(structured_query::FieldReference {
278    ///                 field_path: "field5".to_string(),
279    ///             }),
280    ///             op: structured_query::field_filter::Operator::Equal as i32,
281    ///             value: Some(Value {
282    ///                 value_type: Some(ValueType::IntegerValue(5)),
283    ///             }),
284    ///         },
285    ///     )),
286    /// };
287    /// assert_eq!(structured_query::Filter::from(filter1), expected);
288    /// assert_eq!(structured_query::Filter::from(filter2), expected);
289    /// #     Ok(())
290    /// # }
291    /// ```
292    pub fn equal<T>(&self, value: T) -> Result<Filter>
293    where
294        T: IntoValue,
295    {
296        Filter::field(self.clone(), field_filter::Operator::Equal, value)
297    }
298
299    /// Creates a new `FieldFilter` with the `GreaterThan` operator.
300    ///
301    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
302    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.GREATER_THAN>
303    ///
304    /// # Examples
305    ///
306    /// ```rust
307    /// # fn test_field_path_greater_than() -> firestore_structured_query::Result<()> {
308    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
309    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
310    /// struct S(i64);
311    /// impl IntoValue for S {
312    ///     fn into_value(self) -> Result<Value> {
313    ///         Ok(Value {
314    ///             value_type: Some(ValueType::IntegerValue(self.0)),
315    ///         })
316    ///     }
317    /// }
318    /// let filter1 = FieldPath::raw("field3").greater_than(Value {
319    ///     value_type: Some(ValueType::IntegerValue(3)),
320    /// })?;
321    /// let filter2 = FieldPath::raw("field3").greater_than(S(3))?;
322    /// let expected = structured_query::Filter {
323    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
324    ///         structured_query::FieldFilter {
325    ///             field: Some(structured_query::FieldReference {
326    ///                 field_path: "field3".to_string(),
327    ///             }),
328    ///             op: structured_query::field_filter::Operator::GreaterThan as i32,
329    ///             value: Some(Value {
330    ///                 value_type: Some(ValueType::IntegerValue(3)),
331    ///             }),
332    ///         },
333    ///     )),
334    /// };
335    /// assert_eq!(structured_query::Filter::from(filter1), expected);
336    /// assert_eq!(structured_query::Filter::from(filter2), expected);
337    /// #     Ok(())
338    /// # }
339    /// ```
340    pub fn greater_than<T>(&self, value: T) -> Result<Filter>
341    where
342        T: IntoValue,
343    {
344        Filter::field(self.clone(), field_filter::Operator::GreaterThan, value)
345    }
346
347    /// Creates a new `FieldFilter` with the `GreaterThanOrEqual` operator.
348    ///
349    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
350    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.GREATER_THAN_OR_EQUAL>
351    ///
352    /// # Examples
353    ///
354    /// ```rust
355    /// # fn test_field_path_greater_than_or_equal() -> firestore_structured_query::Result<()> {
356    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
357    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
358    /// struct S(i64);
359    /// impl IntoValue for S {
360    ///     fn into_value(self) -> Result<Value> {
361    ///         Ok(Value {
362    ///             value_type: Some(ValueType::IntegerValue(self.0)),
363    ///         })
364    ///     }
365    /// }
366    /// let filter1 = FieldPath::raw("field4").greater_than_or_equal(Value {
367    ///     value_type: Some(ValueType::IntegerValue(4)),
368    /// })?;
369    /// let filter2 = FieldPath::raw("field4").greater_than_or_equal(S(4))?;
370    /// let expected = structured_query::Filter {
371    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
372    ///         structured_query::FieldFilter {
373    ///             field: Some(structured_query::FieldReference {
374    ///                 field_path: "field4".to_string(),
375    ///             }),
376    ///             op: structured_query::field_filter::Operator::GreaterThanOrEqual as i32,
377    ///             value: Some(Value {
378    ///                 value_type: Some(ValueType::IntegerValue(4)),
379    ///             }),
380    ///         },
381    ///     )),
382    /// };
383    /// assert_eq!(structured_query::Filter::from(filter1), expected);
384    /// assert_eq!(structured_query::Filter::from(filter2), expected);
385    /// #     Ok(())
386    /// # }
387    /// ```
388    pub fn greater_than_or_equal<T>(&self, value: T) -> Result<Filter>
389    where
390        T: IntoValue,
391    {
392        Filter::field(
393            self.clone(),
394            field_filter::Operator::GreaterThanOrEqual,
395            value,
396        )
397    }
398
399    /// Creates a new `FieldFilter` with the `In` operator.
400    ///
401    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
402    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.IN>
403    ///
404    /// # Examples
405    ///
406    /// ```rust
407    /// # fn test_field_path_in() -> firestore_structured_query::Result<()> {
408    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
409    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
410    ///     structured_query, value::ValueType, ArrayValue, Value,
411    /// };
412    /// struct S(Vec<i64>);
413    /// impl IntoValue for S {
414    ///     fn into_value(self) -> Result<Value> {
415    ///         Ok(Value {
416    ///             value_type: Some(ValueType::ArrayValue(ArrayValue {
417    ///                 values: self
418    ///                     .0
419    ///                     .into_iter()
420    ///                     .map(|i| Value {
421    ///                         value_type: Some(ValueType::IntegerValue(i)),
422    ///                     })
423    ///                     .collect(),
424    ///             })),
425    ///         })
426    ///     }
427    /// }
428    /// let filter1 = FieldPath::raw("field8").r#in(Value {
429    ///     value_type: Some(ValueType::ArrayValue(ArrayValue {
430    ///         values: vec![Value {
431    ///             value_type: Some(ValueType::IntegerValue(8)),
432    ///         }],
433    ///     })),
434    /// })?;
435    /// let filter2 = FieldPath::raw("field8").r#in(S(vec![8]))?;
436    /// let expected = structured_query::Filter {
437    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
438    ///         structured_query::FieldFilter {
439    ///             field: Some(structured_query::FieldReference {
440    ///                 field_path: "field8".to_string(),
441    ///             }),
442    ///             op: structured_query::field_filter::Operator::In as i32,
443    ///             value: Some(Value {
444    ///                 value_type: Some(ValueType::ArrayValue(ArrayValue {
445    ///                     values: vec![Value {
446    ///                         value_type: Some(ValueType::IntegerValue(8)),
447    ///                     }],
448    ///                 })),
449    ///             }),
450    ///         },
451    ///     )),
452    /// };
453    /// assert_eq!(structured_query::Filter::from(filter1), expected);
454    /// assert_eq!(structured_query::Filter::from(filter2), expected);
455    /// #     Ok(())
456    /// # }
457    /// ```
458    pub fn r#in<T>(&self, value: T) -> Result<Filter>
459    where
460        T: IntoValue,
461    {
462        Filter::field(self.clone(), field_filter::Operator::In, value)
463    }
464
465    /// Creates a new `UnaryFilter` with the `IsNan` operator.
466    ///
467    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter>
468    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.UnaryFilter.Operator.IS_NAN>
469    ///
470    /// # Examples
471    ///
472    /// ```rust
473    /// # fn test_field_path_is_nan() -> firestore_structured_query::Result<()> {
474    /// use firestore_structured_query::FieldPath;
475    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
476    /// let filter1 = FieldPath::raw("field11").is_nan()?;
477    /// assert_eq!(
478    ///     structured_query::Filter::from(filter1),
479    ///     structured_query::Filter {
480    ///         filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
481    ///             structured_query::UnaryFilter {
482    ///                 op: structured_query::unary_filter::Operator::IsNan as i32,
483    ///                 operand_type: Some(structured_query::unary_filter::OperandType::Field(
484    ///                     structured_query::FieldReference {
485    ///                         field_path: "field11".to_string()
486    ///                     }
487    ///                 )),
488    ///             },
489    ///         )),
490    ///     }
491    /// );
492    /// #     Ok(())
493    /// # }
494    /// ```
495    pub fn is_nan(&self) -> Result<Filter> {
496        Filter::unary(self.clone(), unary_filter::Operator::IsNan)
497    }
498
499    /// Creates a new `UnaryFilter` with the `IsNotNan` operator.
500    ///
501    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter>
502    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.UnaryFilter.Operator.IS_NOT_NAN>
503    ///
504    /// # Examples
505    ///
506    /// ```rust
507    /// # fn test_field_path_is_not_nan() -> firestore_structured_query::Result<()> {
508    /// use firestore_structured_query::FieldPath;
509    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
510    /// let filter1 = FieldPath::raw("field12").is_not_nan()?;
511    /// assert_eq!(
512    ///     structured_query::Filter::from(filter1),
513    ///     structured_query::Filter {
514    ///         filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
515    ///             structured_query::UnaryFilter {
516    ///                 op: structured_query::unary_filter::Operator::IsNotNan as i32,
517    ///                 operand_type: Some(structured_query::unary_filter::OperandType::Field(
518    ///                     structured_query::FieldReference {
519    ///                         field_path: "field12".to_string()
520    ///                     }
521    ///                 )),
522    ///             },
523    ///         )),
524    ///     }
525    /// );
526    /// #     Ok(())
527    /// # }
528    /// ```
529    pub fn is_not_nan(&self) -> Result<Filter> {
530        Filter::unary(self.clone(), unary_filter::Operator::IsNotNan)
531    }
532
533    /// Creates a new `UnaryFilter` with the `IsNotNull` operator.
534    ///
535    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter>
536    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.UnaryFilter.Operator.IS_NOT_NULL>
537    ///
538    /// # Examples
539    ///
540    /// ```rust
541    /// # fn test_field_path_is_not_null() -> firestore_structured_query::Result<()> {
542    /// use firestore_structured_query::FieldPath;
543    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
544    /// let filter1 = FieldPath::raw("field13").is_not_null()?;
545    /// assert_eq!(
546    ///     structured_query::Filter::from(filter1),
547    ///     structured_query::Filter {
548    ///         filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
549    ///             structured_query::UnaryFilter {
550    ///                 op: structured_query::unary_filter::Operator::IsNotNull as i32,
551    ///                 operand_type: Some(structured_query::unary_filter::OperandType::Field(
552    ///                     structured_query::FieldReference {
553    ///                         field_path: "field13".to_string()
554    ///                     }
555    ///                 )),
556    ///             },
557    ///         )),
558    ///     }
559    /// );
560    /// #     Ok(())
561    /// # }
562    /// ```
563    pub fn is_not_null(&self) -> Result<Filter> {
564        Filter::unary(self.clone(), unary_filter::Operator::IsNotNull)
565    }
566
567    /// Creates a new `UnaryFilter` with the `IsNull` operator.
568    ///
569    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter>
570    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.UnaryFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.UnaryFilter.Operator.IS_NULL>
571    ///
572    /// # Examples
573    ///
574    /// ```rust
575    /// # fn test_field_path_is_null() -> firestore_structured_query::Result<()> {
576    /// use firestore_structured_query::FieldPath;
577    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
578    /// let filter1 = FieldPath::raw("field14").is_null()?;
579    /// assert_eq!(
580    ///     structured_query::Filter::from(filter1),
581    ///     structured_query::Filter {
582    ///         filter_type: Some(structured_query::filter::FilterType::UnaryFilter(
583    ///             structured_query::UnaryFilter {
584    ///                 op: structured_query::unary_filter::Operator::IsNull as i32,
585    ///                 operand_type: Some(structured_query::unary_filter::OperandType::Field(
586    ///                     structured_query::FieldReference {
587    ///                         field_path: "field14".to_string()
588    ///                     }
589    ///                 )),
590    ///             },
591    ///         )),
592    ///     }
593    /// );
594    /// #     Ok(())
595    /// # }
596    /// ```
597    pub fn is_null(&self) -> Result<Filter> {
598        Filter::unary(self.clone(), unary_filter::Operator::IsNull)
599    }
600
601    /// Creates a new `FieldFilter` with the `LessThan` operator.
602    ///
603    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
604    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.LESS_THAN>
605    ///
606    /// # Examples
607    ///
608    /// ```rust
609    /// # fn test_field_path_less_than() -> firestore_structured_query::Result<()> {
610    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
611    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
612    /// struct S(i64);
613    /// impl IntoValue for S {
614    ///     fn into_value(self) -> Result<Value> {
615    ///         Ok(Value {
616    ///             value_type: Some(ValueType::IntegerValue(self.0)),
617    ///         })
618    ///     }
619    /// }
620    /// let filter1 = FieldPath::raw("field1").less_than(Value {
621    ///     value_type: Some(ValueType::IntegerValue(1)),
622    /// })?;
623    /// let filter2 = FieldPath::raw("field1").less_than(S(1))?;
624    /// let expected = structured_query::Filter {
625    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
626    ///         structured_query::FieldFilter {
627    ///             field: Some(structured_query::FieldReference {
628    ///                 field_path: "field1".to_string(),
629    ///             }),
630    ///             op: structured_query::field_filter::Operator::LessThan as i32,
631    ///             value: Some(Value {
632    ///                 value_type: Some(ValueType::IntegerValue(1)),
633    ///             }),
634    ///         },
635    ///     )),
636    /// };
637    /// assert_eq!(structured_query::Filter::from(filter1), expected);
638    /// assert_eq!(structured_query::Filter::from(filter2), expected);
639    /// #     Ok(())
640    /// # }
641    /// ```
642    pub fn less_than<T>(&self, value: T) -> Result<Filter>
643    where
644        T: IntoValue,
645    {
646        Filter::field(self.clone(), field_filter::Operator::LessThan, value)
647    }
648
649    /// Creates a new `FieldFilter` with the `LessThanOrEqual` operator.
650    ///
651    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
652    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.LESS_THAN_OR_EQUAL>
653    ///
654    /// # Examples
655    ///
656    /// ```rust
657    /// # fn test_field_path_less_than_or_equal() -> firestore_structured_query::Result<()> {
658    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
659    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
660    /// struct S(i64);
661    /// impl IntoValue for S {
662    ///     fn into_value(self) -> Result<Value> {
663    ///         Ok(Value {
664    ///             value_type: Some(ValueType::IntegerValue(self.0)),
665    ///         })
666    ///     }
667    /// }
668    /// let filter1 = FieldPath::raw("field2").less_than_or_equal(Value {
669    ///     value_type: Some(ValueType::IntegerValue(2)),
670    /// })?;
671    /// let filter2 = FieldPath::raw("field2").less_than_or_equal(S(2))?;
672    /// let expected = structured_query::Filter {
673    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
674    ///         structured_query::FieldFilter {
675    ///             field: Some(structured_query::FieldReference {
676    ///                 field_path: "field2".to_string(),
677    ///             }),
678    ///             op: structured_query::field_filter::Operator::LessThanOrEqual as i32,
679    ///             value: Some(Value {
680    ///                 value_type: Some(ValueType::IntegerValue(2)),
681    ///             }),
682    ///         },
683    ///     )),
684    /// };
685    /// assert_eq!(structured_query::Filter::from(filter1), expected);
686    /// assert_eq!(structured_query::Filter::from(filter2), expected);
687    /// #     Ok(())
688    /// # }
689    /// ```
690    pub fn less_than_or_equal<T>(&self, value: T) -> Result<Filter>
691    where
692        T: IntoValue,
693    {
694        Filter::field(self.clone(), field_filter::Operator::LessThanOrEqual, value)
695    }
696
697    /// Creates a new `FieldFilter` with the `NotEqual` operator.
698    ///
699    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
700    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.NOT_EQUAL>
701    ///
702    /// # Examples
703    ///
704    /// ```rust
705    /// # fn test_field_path_not_equal() -> firestore_structured_query::Result<()> {
706    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
707    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{structured_query, value::ValueType, Value};
708    /// struct S(i64);
709    /// impl IntoValue for S {
710    ///     fn into_value(self) -> Result<Value> {
711    ///         Ok(Value {
712    ///             value_type: Some(ValueType::IntegerValue(self.0)),
713    ///         })
714    ///     }
715    /// }
716    /// let filter1 = FieldPath::raw("field6").not_equal(Value {
717    ///     value_type: Some(ValueType::IntegerValue(6)),
718    /// })?;
719    /// let filter2 = FieldPath::raw("field6").not_equal(S(6))?;
720    /// let expected = structured_query::Filter {
721    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
722    ///         structured_query::FieldFilter {
723    ///             field: Some(structured_query::FieldReference {
724    ///                 field_path: "field6".to_string(),
725    ///             }),
726    ///             op: structured_query::field_filter::Operator::NotEqual as i32,
727    ///             value: Some(Value {
728    ///                 value_type: Some(ValueType::IntegerValue(6)),
729    ///             }),
730    ///         },
731    ///     )),
732    /// };
733    /// assert_eq!(structured_query::Filter::from(filter1), expected);
734    /// assert_eq!(structured_query::Filter::from(filter2), expected);
735    /// #     Ok(())
736    /// # }
737    /// ```
738    pub fn not_equal<T>(&self, value: T) -> Result<Filter>
739    where
740        T: IntoValue,
741    {
742        Filter::field(self.clone(), field_filter::Operator::NotEqual, value)
743    }
744
745    /// Creates a new `FieldFilter` with the `NotIn` operator.
746    ///
747    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter>
748    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.FieldFilter.Operator.ENUM_VALUES.google.firestore.v1.StructuredQuery.FieldFilter.Operator.NOT_IN>
749    ///
750    /// # Examples
751    ///
752    /// ```rust
753    /// # fn test_field_path_not_in() -> firestore_structured_query::Result<()> {
754    /// use firestore_structured_query::{FieldPath, IntoValue, Result};
755    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::{
756    ///     structured_query, value::ValueType, ArrayValue, Value,
757    /// };
758    /// struct S(Vec<i64>);
759    /// impl IntoValue for S {
760    ///     fn into_value(self) -> Result<Value> {
761    ///         Ok(Value {
762    ///             value_type: Some(ValueType::ArrayValue(ArrayValue {
763    ///                 values: self
764    ///                     .0
765    ///                     .into_iter()
766    ///                     .map(|i| Value {
767    ///                         value_type: Some(ValueType::IntegerValue(i)),
768    ///                     })
769    ///                     .collect(),
770    ///             })),
771    ///         })
772    ///     }
773    /// }
774    /// let filter1 = FieldPath::raw("field10").not_in(Value {
775    ///     value_type: Some(ValueType::ArrayValue(ArrayValue {
776    ///         values: vec![Value {
777    ///             value_type: Some(ValueType::IntegerValue(10)),
778    ///         }],
779    ///     })),
780    /// })?;
781    /// let filter2 = FieldPath::raw("field10").not_in(S(vec![10]))?;
782    /// let expected = structured_query::Filter {
783    ///     filter_type: Some(structured_query::filter::FilterType::FieldFilter(
784    ///         structured_query::FieldFilter {
785    ///             field: Some(structured_query::FieldReference {
786    ///                 field_path: "field10".to_string(),
787    ///             }),
788    ///             op: structured_query::field_filter::Operator::NotIn as i32,
789    ///             value: Some(Value {
790    ///                 value_type: Some(ValueType::ArrayValue(ArrayValue {
791    ///                     values: vec![Value {
792    ///                         value_type: Some(ValueType::IntegerValue(10)),
793    ///                     }],
794    ///                 })),
795    ///             }),
796    ///         },
797    ///     )),
798    /// };
799    /// assert_eq!(structured_query::Filter::from(filter1), expected);
800    /// assert_eq!(structured_query::Filter::from(filter2), expected);
801    /// #     Ok(())
802    /// # }
803    /// ```
804    pub fn not_in<T>(&self, value: T) -> Result<Filter>
805    where
806        T: IntoValue,
807    {
808        Filter::field(self.clone(), field_filter::Operator::NotIn, value)
809    }
810}
811
812// for Order
813impl FieldPath {
814    /// Creates a new `Order` with the `Ascending` direction.
815    ///
816    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.Order>
817    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.Direction.ENUM_VALUES.google.firestore.v1.StructuredQuery.Direction.ASCENDING>
818    ///
819    /// # Examples
820    ///
821    /// ```rust
822    /// # fn test_field_path_ascending() -> firestore_structured_query::Result<()> {
823    /// use firestore_structured_query::{FieldPath, Order};
824    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
825    /// let order: Order = FieldPath::raw("field1").ascending();
826    /// assert_eq!(
827    ///     structured_query::Order::from(order),
828    ///     structured_query::Order {
829    ///         field: Some(structured_query::FieldReference {
830    ///             field_path: "field1".to_string()
831    ///         }),
832    ///         direction: structured_query::Direction::Ascending as i32
833    ///     }
834    /// );
835    /// #     Ok(())
836    /// # }
837    /// ```
838    pub fn ascending(&self) -> Order {
839        Order::new(self.clone(), structured_query::Direction::Ascending)
840    }
841
842    /// Creates a new `Order` with the `Descending` direction.
843    ///
844    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.Order>
845    /// <https://firebase.google.com/docs/firestore/reference/rpc/google.firestore.v1#google.firestore.v1.StructuredQuery.Direction.ENUM_VALUES.google.firestore.v1.StructuredQuery.Direction.DESCENDING>
846    ///
847    /// # Examples
848    ///
849    /// ```rust
850    /// # fn test_field_path_descending() -> firestore_structured_query::Result<()> {
851    /// use firestore_structured_query::{FieldPath, Order};
852    /// use googleapis_tonic_google_firestore_v1::google::firestore::v1::structured_query;
853    /// let order: Order = FieldPath::raw("field1").descending();
854    /// assert_eq!(
855    ///     structured_query::Order::from(order),
856    ///     structured_query::Order {
857    ///         field: Some(structured_query::FieldReference {
858    ///             field_path: "field1".to_string()
859    ///         }),
860    ///         direction: structured_query::Direction::Descending as i32
861    ///     }
862    /// );
863    /// #     Ok(())
864    /// # }
865    /// ```
866    pub fn descending(&self) -> Order {
867        Order::new(self.clone(), structured_query::Direction::Descending)
868    }
869}
870
871impl std::convert::From<FieldPath> for structured_query::FieldReference {
872    fn from(FieldPath(field_path): FieldPath) -> Self {
873        structured_query::FieldReference { field_path }
874    }
875}