derive_and_ext/
derive_and_ext.rs1use 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