derive_and_ext/
derive_and_ext.rs

1use rust_queries_builder::{QueryExt, QueryBuilder};
2use key_paths_derive::Keypaths;
3
4#[derive(Debug, Clone, Keypaths, QueryBuilder)]
5struct Product {
6    id: u32,
7    name: String,
8    price: f64,
9    category: String,
10    stock: u32,
11}
12
13fn main() {
14    println!("Derive Macros and Extension Traits Example");
15    println!("===========================================\n");
16
17    let products = vec![
18        Product {
19            id: 1,
20            name: "Laptop".to_string(),
21            price: 999.99,
22            category: "Electronics".to_string(),
23            stock: 5,
24        },
25        Product {
26            id: 2,
27            name: "Mouse".to_string(),
28            price: 29.99,
29            category: "Electronics".to_string(),
30            stock: 50,
31        },
32        Product {
33            id: 3,
34            name: "Keyboard".to_string(),
35            price: 79.99,
36            category: "Electronics".to_string(),
37            stock: 30,
38        },
39        Product {
40            id: 4,
41            name: "Monitor".to_string(),
42            price: 299.99,
43            category: "Electronics".to_string(),
44            stock: 12,
45        },
46        Product {
47            id: 5,
48            name: "Desk Chair".to_string(),
49            price: 199.99,
50            category: "Furniture".to_string(),
51            stock: 8,
52        },
53    ];
54
55    println!("1. Using Extension Trait - Direct .query() on Vec");
56    println!("   Query: products.query().where_(price > 100).all()");
57    
58    let query = products
59        .query()
60        .where_(Product::price_r(), |&p| p > 100.0);
61    let expensive = query.all();
62    
63    println!("   Found {} expensive products:", expensive.len());
64    for product in &expensive {
65        println!("   - {} (${:.2})", product.name, product.price);
66    }
67    println!();
68
69    println!("2. Using Extension Trait - Direct .lazy_query() on Vec");
70    println!("   Query: products.lazy_query().where_(stock < 10).collect()");
71    
72    let low_stock: Vec<_> = products
73        .lazy_query()
74        .where_(Product::stock_r(), |&s| s < 10)
75        .collect();
76    
77    println!("   Found {} low stock products:", low_stock.len());
78    for product in &low_stock {
79        println!("   - {} (stock: {})", product.name, product.stock);
80    }
81    println!();
82
83    println!("3. Using Extension Trait - Chained Operations");
84    println!("   Query: products.lazy_query().where_(category == Electronics).take(2).select(name).collect()");
85    
86    let names: Vec<String> = products
87        .lazy_query()
88        .where_(Product::category_r(), |cat| cat == "Electronics")
89        .take_lazy(2)
90        .select_lazy(Product::name_r())
91        .collect();
92    
93    println!("   First 2 electronics:");
94    for name in &names {
95        println!("   - {}", name);
96    }
97    println!();
98
99    println!("4. Using QueryBuilder Derive - Static Methods");
100    println!("   Query: Product::query(&products).where_(price > 50).count()");
101    
102    let query4 = Product::query(&products)
103        .where_(Product::price_r(), |&p| p > 50.0);
104    let count = query4.count();
105    
106    println!("   Products over $50: {}", count);
107    println!();
108
109    println!("5. Using QueryBuilder Derive - Lazy Static Methods");
110    println!("   Query: Product::lazy_query(&products).first()");
111    
112    if let Some(first) = Product::lazy_query(&products).first() {
113        println!("   First product: {} (${:.2})", first.name, first.price);
114    }
115    println!();
116
117    println!("6. Complex Chain with Extension Trait");
118    println!("   Query: products.lazy_query()");
119    println!("          .where_(category == Electronics)");
120    println!("          .where_(price < 500)");
121    println!("          .map(|p| format!(\"{{}} - ${{:.2}}\", p.name, p.price))");
122    println!("          .collect()");
123    
124    let formatted: Vec<String> = products
125        .lazy_query()
126        .where_(Product::category_r(), |cat| cat == "Electronics")
127        .where_(Product::price_r(), |&p| p < 500.0)
128        .map_items(|p| format!("{} - ${:.2}", p.name, p.price))
129        .collect();
130    
131    println!("   Affordable electronics:");
132    for item in &formatted {
133        println!("   - {}", item);
134    }
135    println!();
136
137    println!("7. Aggregation with Extension Trait");
138    println!("   Query: products.lazy_query().sum_by(Product::stock())");
139    
140    let total_stock = products
141        .lazy_query()
142        .sum_by(Product::stock_r());
143    
144    println!("   Total stock across all products: {}", total_stock);
145    println!();
146
147    println!("8. Find with Extension Trait");
148    println!("   Query: products.lazy_query().find(|p| p.name.contains(\"Chair\"))");
149    
150    if let Some(chair) = products.lazy_query().find(|p| p.name.contains("Chair")) {
151        println!("   Found: {} in {}", chair.name, chair.category);
152    }
153    println!();
154
155    println!("9. Early Termination with Extension Trait");
156    println!("   Query: products.lazy_query().where_(price > 1000).any()");
157    
158    let has_luxury = products
159        .lazy_query()
160        .where_(Product::price_r(), |&p| p > 1000.0)
161        .any();
162    
163    println!("   Has products over $1000: {}", has_luxury);
164    println!();
165
166    println!("10. Slice Extension Trait");
167    println!("    Query: (&products[..]).lazy_query().count()");
168    
169    let slice_count = (&products[..])
170        .lazy_query()
171        .count();
172    
173    println!("    Count from slice: {}", slice_count);
174    println!();
175
176    println!("Summary:");
177    println!("--------");
178    println!("✓ Extension trait QueryExt adds .query() and .lazy_query() to containers");
179    println!("✓ Derive macro QueryBuilder adds static methods Product::query() and Product::lazy_query()");
180    println!("✓ Both approaches provide the same query functionality");
181    println!("✓ Extension trait is more ergonomic: products.query() vs Query::new(&products)");
182    println!("✓ All iterator optimizations (fusion, early termination) still apply");
183}
184