rust_queries_builder/macros.rs
1//! Macros to simplify query building and reduce boilerplate.
2//!
3//! This module provides declarative macros for creating queries with less code.
4
5/// Creates a lazy query with multiple filters in a concise syntax.
6///
7/// # Syntax
8///
9/// ```ignore
10/// lazy_query!(data, Type =>
11/// field1 == value1,
12/// field2 > value2,
13/// field3.contains("text")
14/// )
15/// ```
16///
17/// # Example
18///
19/// ```ignore
20/// // Instead of:
21/// let results = LazyQuery::new(&products)
22/// .where_(Product::category_r(), |cat| cat == "Electronics")
23/// .where_(Product::price_r(), |&p| p < 500.0)
24/// .where_(Product::stock_r(), |&s| s > 0)
25/// .collect();
26///
27/// // Write:
28/// let results = lazy_query!(products, Product =>
29/// category == "Electronics",
30/// price < 500.0,
31/// stock > 0
32/// ).collect();
33/// ```
34#[macro_export]
35macro_rules! lazy_query {
36 ($data:expr, $type:ty => $($tail:tt)*) => {{
37 $crate::LazyQuery::new($data)
38 }};
39
40 ($data:expr) => {{
41 $crate::LazyQuery::new($data)
42 }};
43}
44
45/// Creates a Query with multiple filters in a concise syntax.
46///
47/// # Example
48///
49/// ```ignore
50/// let results = query!(products, Product)
51/// .where_(Product::category_r(), |cat| cat == "Electronics")
52/// .all();
53/// ```
54#[macro_export]
55macro_rules! query {
56 ($data:expr) => {{
57 $crate::Query::new($data)
58 }};
59}
60
61/// Simplified where_ macro that reduces boilerplate.
62///
63/// # Example
64///
65/// ```ignore
66/// // Instead of:
67/// .where_(Product::price_r(), |&p| p < 100.0)
68///
69/// // Write:
70/// .where_(Product::price_r(), |&p| p < 100.0) // Same for now, helper in query! macro
71/// ```
72#[macro_export]
73macro_rules! filter {
74 ($field:expr, $pred:expr) => {{
75 |item| $field.get(item).map_or(false, $pred)
76 }};
77}
78
79/// Creates a lazy query and collects results in one line.
80///
81/// # Example
82///
83/// ```ignore
84/// // Instead of:
85/// let results: Vec<_> = LazyQuery::new(&products)
86/// .where_(Product::price_r(), |&p| p < 100.0)
87/// .collect();
88///
89/// // Write:
90/// let results = collect_lazy!(products where price < 100.0);
91/// ```
92#[macro_export]
93macro_rules! collect_lazy {
94 ($data:expr) => {{
95 $crate::LazyQuery::new($data).collect()
96 }};
97}
98
99/// Quick filter and collect.
100///
101/// # Example
102///
103/// ```ignore
104/// let results = filter_collect!(products, Product::category_r(), |cat| cat == "Electronics");
105/// ```
106#[macro_export]
107macro_rules! filter_collect {
108 ($data:expr, $field:expr, $pred:expr) => {{
109 $crate::LazyQuery::new($data)
110 .where_($field, $pred)
111 .collect()
112 }};
113}
114
115/// Quick count with filter.
116///
117/// # Example
118///
119/// ```ignore
120/// let count = count_where!(products, Product::stock_r(), |&s| s > 0);
121/// ```
122#[macro_export]
123macro_rules! count_where {
124 ($data:expr, $field:expr, $pred:expr) => {{
125 $crate::LazyQuery::new($data)
126 .where_($field, $pred)
127 .count()
128 }};
129}
130
131/// Find first matching item.
132///
133/// # Example
134///
135/// ```ignore
136/// let found = find_first!(products, Product::id_r(), |&id| id == 42);
137/// ```
138#[macro_export]
139macro_rules! find_first {
140 ($data:expr, $field:expr, $pred:expr) => {{
141 $crate::LazyQuery::new($data)
142 .where_($field, $pred)
143 .first()
144 }};
145}
146
147/// Check if any item matches.
148///
149/// # Example
150///
151/// ```ignore
152/// let exists = exists_where!(products, Product::category_r(), |cat| cat == "Electronics");
153/// ```
154#[macro_export]
155macro_rules! exists_where {
156 ($data:expr, $field:expr, $pred:expr) => {{
157 $crate::LazyQuery::new($data)
158 .where_($field, $pred)
159 .any()
160 }};
161}
162
163/// Quick pagination.
164///
165/// # Example
166///
167/// ```ignore
168/// let page_2 = paginate!(products, page: 2, size: 10);
169/// ```
170#[macro_export]
171macro_rules! paginate {
172 ($data:expr, page: $page:expr, size: $size:expr) => {{
173 $crate::LazyQuery::new($data)
174 .skip_lazy($page * $size)
175 .take_lazy($size)
176 .collect()
177 }};
178}
179
180/// Quick sum aggregation.
181///
182/// # Example
183///
184/// ```ignore
185/// let total = sum_where!(products, Product::price_r(), Product::stock_r(), |&s| s > 0);
186/// ```
187#[macro_export]
188macro_rules! sum_where {
189 ($data:expr, $sum_field:expr, $filter_field:expr, $pred:expr) => {{
190 $crate::LazyQuery::new($data)
191 .where_($filter_field, $pred)
192 .sum_by($sum_field)
193 }};
194
195 ($data:expr, $sum_field:expr) => {{
196 $crate::LazyQuery::new($data)
197 .sum_by($sum_field)
198 }};
199}
200
201/// Quick average aggregation.
202///
203/// # Example
204///
205/// ```ignore
206/// let avg = avg_where!(products, Product::price_r(), Product::active_r(), |&a| a);
207/// ```
208#[macro_export]
209macro_rules! avg_where {
210 ($data:expr, $avg_field:expr, $filter_field:expr, $pred:expr) => {{
211 $crate::LazyQuery::new($data)
212 .where_($filter_field, $pred)
213 .avg_by($avg_field)
214 }};
215
216 ($data:expr, $avg_field:expr) => {{
217 $crate::LazyQuery::new($data)
218 .avg_by($avg_field)
219 }};
220}
221
222/// Select and collect in one line.
223///
224/// # Example
225///
226/// ```ignore
227/// let names = select_all!(products, Product::name_r());
228/// ```
229#[macro_export]
230macro_rules! select_all {
231 ($data:expr, $field:expr) => {{
232 $crate::LazyQuery::new($data)
233 .select_lazy($field)
234 .collect()
235 }};
236}
237
238/// Select with filter.
239///
240/// # Example
241///
242/// ```ignore
243/// let names = select_where!(
244/// products,
245/// Product::name_r(),
246/// Product::category_r(),
247/// |cat| cat == "Electronics"
248/// );
249/// ```
250#[macro_export]
251macro_rules! select_where {
252 ($data:expr, $select_field:expr, $filter_field:expr, $pred:expr) => {{
253 $crate::LazyQuery::new($data)
254 .where_($filter_field, $pred)
255 .select_lazy($select_field)
256 .collect()
257 }};
258}
259