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}
19
20#[derive(Debug, Clone, PartialEq)]
21pub enum FilterExpr {
22 Filter(Filter),
23 All(Vec<FilterExpr>),
24 Any(Vec<FilterExpr>),
25 Not(Box<FilterExpr>),
26 Relation(RelationFilter),
27 Coalesce(CoalesceFilter),
30 Json(JsonFilter),
34 #[cfg(feature = "postgis")]
40 #[cfg(feature = "postgis")]
41 Spatial(SpatialFilter),
42 VectorDistance(VectorDistanceFilter),
49}
50
51impl From<Filter> for FilterExpr {
52 fn from(value: Filter) -> Self {
53 Self::Filter(value)
54 }
55}
56
57impl RelationFilter {
58 pub fn new(
59 quantifier: RelationQuantifier,
60 parent_table: &'static str,
61 parent_column: &'static str,
62 related_table: &'static str,
63 related_column: &'static str,
64 filter: FilterExpr,
65 ) -> Self {
66 Self {
67 quantifier,
68 parent_table,
69 parent_column,
70 related_table,
71 related_column,
72 filter: Box::new(filter),
73 }
74 }
75}
76
77impl FilterExpr {
78 pub fn all(filters: impl IntoIterator<Item = FilterExpr>) -> Self {
79 Self::All(filters.into_iter().collect())
80 }
81
82 pub fn any(filters: impl IntoIterator<Item = FilterExpr>) -> Self {
83 Self::Any(filters.into_iter().collect())
84 }
85
86 #[allow(clippy::should_implement_trait)]
89 pub fn not(self) -> Self {
90 match self {
91 Self::Not(inner) => *inner,
92 inner => Self::Not(Box::new(inner)),
93 }
94 }
95
96 pub fn and(self, other: impl Into<FilterExpr>) -> Self {
97 match (self, other.into()) {
98 (Self::All(mut left), Self::All(right)) => {
99 left.extend(right);
100 Self::All(left)
101 }
102 (Self::All(mut left), right) => {
103 left.push(right);
104 Self::All(left)
105 }
106 (left, Self::All(mut right)) => {
107 let mut filters = vec![left];
108 filters.append(&mut right);
109 Self::All(filters)
110 }
111 (left, right) => Self::All(vec![left, right]),
112 }
113 }
114
115 pub fn or(self, other: impl Into<FilterExpr>) -> Self {
116 match (self, other.into()) {
117 (Self::Any(mut left), Self::Any(right)) => {
118 left.extend(right);
119 Self::Any(left)
120 }
121 (Self::Any(mut left), right) => {
122 left.push(right);
123 Self::Any(left)
124 }
125 (left, Self::Any(mut right)) => {
126 let mut filters = vec![left];
127 filters.append(&mut right);
128 Self::Any(filters)
129 }
130 (left, right) => Self::Any(vec![left, right]),
131 }
132 }
133}