# Macro Helpers Guide
## Overview
Version 0.4.0 introduces **12 helper macros** that reduce boilerplate code and make common query patterns more concise.
## Quick Reference
| `lazy_query!` | Create LazyQuery | ~15 chars |
| `query!` | Create Query | ~10 chars |
| `collect_lazy!` | Collect all items | ~20 chars |
| `filter_collect!` | Filter and collect | ~35 chars |
| `count_where!` | Count with filter | ~30 chars |
| `find_first!` | Find first match | ~30 chars |
| `exists_where!` | Check existence | ~30 chars |
| `paginate!` | Pagination | ~45 chars |
| `sum_where!` | Sum with filter | ~25 chars |
| `avg_where!` | Average with filter | ~25 chars |
| `select_all!` | Select field | ~20 chars |
| `select_where!` | Select with filter | ~40 chars |
**Total savings**: 20-45 characters per operation!
## Usage Examples
### 1. lazy_query! - Create LazyQuery
**Before:**
```rust
let query = LazyQuery::new(&products);
```
**After:**
```rust
let query = lazy_query!(&products);
```
**Saved**: 15 characters
### 2. collect_lazy! - Simple Collection
**Before:**
```rust
let results: Vec<_> = LazyQuery::new(&products).collect();
```
**After:**
```rust
let results = collect_lazy!(&products);
```
**Saved**: 20 characters
### 3. filter_collect! - Filter and Collect
**Before:**
```rust
let electronics: Vec<_> = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Electronics")
.collect();
```
**After:**
```rust
let electronics = filter_collect!(
&products,
Product::category_r(),
|cat| cat == "Electronics"
);
```
**Saved**: ~35 characters, more readable
### 4. count_where! - Count with Filter
**Before:**
```rust
let count = LazyQuery::new(&products)
.where_(Product::stock_r(), |&s| s > 0)
.count();
```
**After:**
```rust
**Saved**: ~30 characters
### 5. find_first! - Find First Match
**Before:**
```rust
let found = LazyQuery::new(&products)
.where_(Product::price_r(), |&p| p > 500.0)
.first();
```
**After:**
```rust
**Saved**: ~30 characters
### 6. exists_where! - Existence Check
**Before:**
```rust
let has_furniture = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Furniture")
.any();
```
**After:**
```rust
let has_furniture = exists_where!(
&products,
Product::category_r(),
|cat| cat == "Furniture"
);
```
**Saved**: ~30 characters
### 7. paginate! - Easy Pagination
**Before:**
```rust
let page_2: Vec<_> = LazyQuery::new(&products)
.skip_lazy(2 * 10) // page * size
.take_lazy(10)
.collect();
```
**After:**
```rust
let page_2 = paginate!(&products, page: 2, size: 10);
```
**Saved**: ~45 characters, much clearer intent
### 8. sum_where! - Sum with Filter
**Before:**
```rust
let total: f64 = LazyQuery::new(&products)
.where_(Product::active_r(), |&a| a)
.sum_by(Product::price_r());
```
**After:**
```rust
let total = sum_where!(
&products,
Product::price_r(),
Product::active_r(),
|&a| a
);
```
**Saved**: ~25 characters
**Without filter:**
```rust
let total = sum_where!(&products, Product::price_r());
```
### 9. avg_where! - Average with Filter
**Before:**
```rust
let avg = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Electronics")
.avg_by(Product::price_r())
.unwrap_or(0.0);
```
**After:**
```rust
let avg = avg_where!(
&products,
Product::price_r(),
Product::category_r(),
|cat| cat == "Electronics"
).unwrap_or(0.0);
```
**Saved**: ~25 characters
**Without filter:**
```rust
let avg = avg_where!(&products, Product::price_r()).unwrap_or(0.0);
```
### 10. select_all! - Select Field
**Before:**
```rust
let names: Vec<String> = LazyQuery::new(&products)
.select_lazy(Product::name_r())
.collect();
```
**After:**
```rust
let names: Vec<String> = select_all!(&products, Product::name_r());
```
**Saved**: ~20 characters
### 11. select_where! - Select with Filter
**Before:**
```rust
let furniture_names: Vec<String> = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Furniture")
.select_lazy(Product::name_r())
.collect();
```
**After:**
```rust
let furniture_names: Vec<String> = select_where!(
&products,
Product::name_r(),
Product::category_r(),
|cat| cat == "Furniture"
);
```
**Saved**: ~40 characters
### 12. query! - Create Query
**Before:**
```rust
let query = Query::new(&products);
```
**After:**
```rust
let query = query!(&products);
```
**Saved**: ~10 characters
## Real-World Examples
### Before Macros (Verbose)
```rust
// Count active electronics
let count = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Electronics")
.where_(Product::active_r(), |&a| a)
.count();
// Get page 3
let page: Vec<_> = LazyQuery::new(&products)
.skip_lazy(3 * 20)
.take_lazy(20)
.collect();
// Find expensive item
let expensive = LazyQuery::new(&products)
.where_(Product::price_r(), |&p| p > 1000.0)
.first();
// Get all names
let names: Vec<String> = LazyQuery::new(&products)
.select_lazy(Product::name_r())
.collect();
// Total value of active products
let total: f64 = LazyQuery::new(&products)
.where_(Product::active_r(), |&a| a)
.sum_by(Product::price_r());
```
**Total**: ~500 characters
### After Macros (Concise)
```rust
// Count active electronics (still need chaining for multiple filters)
// Get page 3
let page = paginate!(&products, page: 3, size: 20);
// Find expensive item
// Get all names
let names: Vec<String> = select_all!(&products, Product::name_r());
// Total value of active products
let total = sum_where!(&products, Product::price_r(), Product::active_r(), |&a| a);
```
**Total**: ~350 characters
**Savings**: 30% less code!
## When to Use Macros
### ✅ Use Macros For:
- Single filter + terminal operation
- Common patterns (pagination, counting, sum)
- Quick prototyping
- Simple queries
- Code golf / conciseness
### ⚠️ Use Full API For:
- Multiple filters (still need chaining)
- Complex predicates
- Custom transformations
- When clarity is more important than brevity
- Library/framework code
## Combining Macros with Full API
You can mix macros and full API:
```rust
// Start with macro
let base = lazy_query!(&products);
// Continue with full API
let results: Vec<_> = base
.where_(Product::category_r(), |cat| cat == "Electronics")
.where_(Product::price_r(), |&p| p < 500.0)
.where_(Product::stock_r(), |&s| s > 0)
.take_lazy(10)
.collect();
```
## Performance
**All macros are zero-cost abstractions!**
They expand at compile-time to the same code you would write manually:
```rust
// This macro:
// Expands to exactly:
LazyQuery::new(&products)
.where_(Product::stock_r(), |&s| s > 0)
.count()
// Same compiled code, same performance!
```
## Type Safety
Macros maintain full type safety:
```rust
// ✅ Compiles
// ❌ Won't compile - type mismatch
let count = count_where!(&products, Product::price_r(), |p| p == "100");
// ❌ Won't compile - wrong field
All compile-time checking is preserved!
## Complete Example
Run the demonstration:
```bash
cargo run --example macro_helpers
```
**Output shows:**
```
✅ 12 helper macros provided:
• lazy_query! - Create LazyQuery
• query! - Create Query
• collect_lazy! - Quick collect
[... all 12 macros ...]
📊 Benefits:
• Less typing (20-45 characters saved per operation)
• More readable code
• Common patterns encapsulated
• Same performance (zero-cost abstraction)
• Type-safe (compile-time checked)
```
## Macro List
### Creation Macros
```rust
lazy_query!(&data) // → LazyQuery::new(&data)
query!(&data) // → Query::new(&data)
```
### Collection Macros
```rust
collect_lazy!(&data) // Collect all
filter_collect!(&data, field, pred) // Filter + collect
select_all!(&data, field) // Select field
select_where!(&data, sel_field, filt_field, pred) // Select with filter
```
### Search Macros
```rust
find_first!(&data, field, pred) // Find first match
exists_where!(&data, field, pred) // Check existence
count_where!(&data, field, pred) // Count matches
```
### Aggregation Macros
```rust
sum_where!(&data, sum_field, filter_field, pred) // Sum with filter
sum_where!(&data, sum_field) // Sum all
avg_where!(&data, avg_field, filter_field, pred) // Average with filter
avg_where!(&data, avg_field) // Average all
```
### Utility Macros
```rust
paginate!(&data, page: p, size: s) // Easy pagination
```
## Migration Guide
### Step 1: Import Macros
```rust
use rust_queries_builder::{
lazy_query, filter_collect, count_where,
find_first, paginate, sum_where, // ... etc
};
```
### Step 2: Replace Common Patterns
```rust
// Before
let count = LazyQuery::new(&products).where_(...).count();
// After
let count = count_where!(&products, field, pred);
```
### Step 3: Keep Complex Queries As-Is
```rust
// Complex queries still use full API
let results: Vec<_> = LazyQuery::new(&products)
.where_(Product::category_r(), |cat| cat == "Electronics")
.where_(Product::price_r(), |&p| p > 100.0 && p < 500.0)
.where_(Product::stock_r(), |&s| s > 0)
.where_(Product::rating_r(), |&r| r > 4.5)
.take_lazy(10)
.collect();
```
## See Also
- [examples/macro_helpers.rs](examples/macro_helpers.rs) - Complete demonstrations
- [src/macros.rs](src/macros.rs) - Macro implementations
- [LAZY_EVALUATION.md](LAZY_EVALUATION.md) - Lazy query guide