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}