cratestack_sql/filter/
expr.rs1pub use cratestack_policy::RelationQuantifier;
2
3use super::coalesce::CoalesceFilter;
4use super::filter::Filter;
5use super::json::JsonFilter;
6#[cfg(feature = "postgis")]
7use super::spatial::SpatialFilter;
8use super::vector::VectorDistanceFilter;
9
10#[derive(Debug, Clone, PartialEq)]
11pub struct RelationFilter {
12 pub quantifier: RelationQuantifier,
13 pub parent_table: &'static str,
14 pub parent_column: &'static str,
15 pub related_table: &'static str,
16 pub related_column: &'static str,
17 pub filter: Box<FilterExpr>,
18 pub scope: crate::RelatedReadScope,
21}
22
23#[derive(Debug, Clone, PartialEq)]
24pub enum FilterExpr {
25 Filter(Filter),
26 All(Vec<FilterExpr>),
27 Any(Vec<FilterExpr>),
28 Not(Box<FilterExpr>),
29 Relation(RelationFilter),
30 Coalesce(CoalesceFilter),
33 Json(JsonFilter),
37 #[cfg(feature = "postgis")]
43 #[cfg(feature = "postgis")]
44 Spatial(SpatialFilter),
45 VectorDistance(VectorDistanceFilter),
52}
53
54impl From<Filter> for FilterExpr {
55 fn from(value: Filter) -> Self {
56 Self::Filter(value)
57 }
58}
59
60impl RelationFilter {
61 pub fn new(
62 quantifier: RelationQuantifier,
63 parent_table: &'static str,
64 parent_column: &'static str,
65 related_table: &'static str,
66 related_column: &'static str,
67 filter: FilterExpr,
68 scope: crate::RelatedReadScope,
69 ) -> Self {
70 Self {
71 quantifier,
72 parent_table,
73 parent_column,
74 related_table,
75 related_column,
76 filter: Box::new(filter),
77 scope,
78 }
79 }
80}
81
82impl FilterExpr {
83 pub fn all(filters: impl IntoIterator<Item = FilterExpr>) -> Self {
84 Self::All(filters.into_iter().collect())
85 }
86
87 pub fn any(filters: impl IntoIterator<Item = FilterExpr>) -> Self {
88 Self::Any(filters.into_iter().collect())
89 }
90
91 #[allow(clippy::should_implement_trait)]
94 pub fn not(self) -> Self {
95 match self {
96 Self::Not(inner) => *inner,
97 inner => Self::Not(Box::new(inner)),
98 }
99 }
100
101 pub fn and(self, other: impl Into<FilterExpr>) -> Self {
102 match (self, other.into()) {
103 (Self::All(mut left), Self::All(right)) => {
104 left.extend(right);
105 Self::All(left)
106 }
107 (Self::All(mut left), right) => {
108 left.push(right);
109 Self::All(left)
110 }
111 (left, Self::All(mut right)) => {
112 let mut filters = vec![left];
113 filters.append(&mut right);
114 Self::All(filters)
115 }
116 (left, right) => Self::All(vec![left, right]),
117 }
118 }
119
120 pub fn or(self, other: impl Into<FilterExpr>) -> Self {
121 match (self, other.into()) {
122 (Self::Any(mut left), Self::Any(right)) => {
123 left.extend(right);
124 Self::Any(left)
125 }
126 (Self::Any(mut left), right) => {
127 left.push(right);
128 Self::Any(left)
129 }
130 (left, Self::Any(mut right)) => {
131 let mut filters = vec![left];
132 filters.append(&mut right);
133 Self::Any(filters)
134 }
135 (left, right) => Self::Any(vec![left, right]),
136 }
137 }
138}