|
2 | 2 |
|
3 | 3 | use crate::{Asset, Assets, Bbox, Error, Fields, Link, Result, STAC_VERSION, Version}; |
4 | 4 | use chrono::{DateTime, FixedOffset, NaiveDateTime, Utc}; |
| 5 | +use cql2::Expr; |
5 | 6 | use geojson::{Feature, Geometry, feature::Id}; |
6 | 7 | use indexmap::IndexMap; |
7 | 8 | use serde::{Deserialize, Deserializer, Serialize}; |
@@ -602,6 +603,22 @@ impl Item { |
602 | 603 | properties, |
603 | 604 | }) |
604 | 605 | } |
| 606 | + |
| 607 | + /// Returns true if this item matches the given CQL2 expression. |
| 608 | + /// |
| 609 | + /// # Examples |
| 610 | + /// |
| 611 | + /// ``` |
| 612 | + /// use stac::Item; |
| 613 | + /// |
| 614 | + /// let item = Item::new("an-item"); |
| 615 | + /// assert!(item.clone().matches_cql2("id = 'an-item'".parse().unwrap()).unwrap()); |
| 616 | + /// assert!(!item.matches_cql2("id = 'another-item'".parse().unwrap()).unwrap()); |
| 617 | + /// ``` |
| 618 | + pub fn matches_cql2(self, expr: Expr) -> Result<bool> { |
| 619 | + let result = self.into_flat_item(true)?.matches_cql2(expr)?; |
| 620 | + Ok(result) |
| 621 | + } |
605 | 622 | } |
606 | 623 |
|
607 | 624 | impl Assets for Item { |
@@ -685,6 +702,15 @@ impl TryFrom<Item> for Feature { |
685 | 702 | } |
686 | 703 | } |
687 | 704 |
|
| 705 | +impl FlatItem { |
| 706 | + /// Returns true if the item matches the given CQL2 expression. |
| 707 | + pub fn matches_cql2(self, expr: Expr) -> Result<bool> { |
| 708 | + let value = serde_json::to_value(self)?; |
| 709 | + let result = expr.matches(Some(&value)).map_err(Box::new)?; |
| 710 | + Ok(result) |
| 711 | + } |
| 712 | +} |
| 713 | + |
688 | 714 | fn default_stac_version() -> Version { |
689 | 715 | STAC_VERSION |
690 | 716 | } |
@@ -945,4 +971,19 @@ mod tests { |
945 | 971 | fn read_invalid_item_datetimes() { |
946 | 972 | let _: Item = crate::read("data/invalid-datetimes.json").unwrap(); |
947 | 973 | } |
| 974 | + |
| 975 | + #[test] |
| 976 | + fn matches_cql2() { |
| 977 | + let item = Item::new("an-item"); |
| 978 | + assert!( |
| 979 | + item.clone() |
| 980 | + .matches_cql2("id = 'an-item'".parse().unwrap()) |
| 981 | + .unwrap() |
| 982 | + ); |
| 983 | + assert!( |
| 984 | + !item |
| 985 | + .matches_cql2("id = 'another-item'".parse().unwrap()) |
| 986 | + .unwrap() |
| 987 | + ); |
| 988 | + } |
948 | 989 | } |
0 commit comments