1use rust_queries_builder::LazyQuery;
7use key_paths_derive::Keypaths;
8use std::collections::HashMap;
9use std::sync::{Arc, RwLock};
10
11#[derive(Debug, Clone, Keypaths)]
12struct Product {
13 id: u32,
14 name: String,
15 price: f64,
16 category: String,
17 stock: u32,
18 rating: f64,
19 active: bool,
20}
21
22type ProductId = String;
23type SharedProduct = Arc<RwLock<Product>>;
24type ProductMap = HashMap<ProductId, SharedProduct>;
25
26fn create_sample_data() -> ProductMap {
27 let mut map = HashMap::new();
28
29 let products = vec![
30 Product { id: 1, name: "Laptop Pro".to_string(), price: 1299.99, category: "Electronics".to_string(), stock: 15, rating: 4.8, active: true },
31 Product { id: 2, name: "Wireless Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.5, active: true },
32 Product { id: 3, name: "Mechanical Keyboard".to_string(), price: 129.99, category: "Electronics".to_string(), stock: 30, rating: 4.7, active: true },
33 Product { id: 4, name: "Office Chair".to_string(), price: 299.99, category: "Furniture".to_string(), stock: 20, rating: 4.6, active: true },
34 Product { id: 5, name: "Standing Desk".to_string(), price: 499.99, category: "Furniture".to_string(), stock: 10, rating: 4.9, active: true },
35 Product { id: 6, name: "USB-C Hub".to_string(), price: 49.99, category: "Electronics".to_string(), stock: 100, rating: 4.3, active: true },
36 Product { id: 7, name: "Monitor 27\"".to_string(), price: 349.99, category: "Electronics".to_string(), stock: 25, rating: 4.7, active: true },
37 Product { id: 8, name: "Desk Lamp".to_string(), price: 39.99, category: "Furniture".to_string(), stock: 40, rating: 4.2, active: true },
38 Product { id: 9, name: "Webcam HD".to_string(), price: 79.99, category: "Electronics".to_string(), stock: 35, rating: 4.4, active: true },
39 Product { id: 10, name: "Bookshelf".to_string(), price: 149.99, category: "Furniture".to_string(), stock: 15, rating: 4.5, active: false },
40 ];
41
42 for product in products {
43 let id = format!("PROD-{:03}", product.id);
44 map.insert(id, Arc::new(RwLock::new(product)));
45 }
46
47 map
48}
49
50fn extract_products(map: &ProductMap) -> Vec<Product> {
52 map.values()
53 .filter_map(|arc_lock| {
54 arc_lock.read().ok().map(|guard| guard.clone())
55 })
56 .collect()
57}
58
59fn main() {
60 println!("\n╔══════════════════════════════════════════════════════════════════╗");
61 println!("║ Arc<RwLock<T>> HashMap Lazy Query Demo ║");
62 println!("║ Thread-safe shared data with lazy evaluation ║");
63 println!("╚══════════════════════════════════════════════════════════════════╝\n");
64
65 let product_map = create_sample_data();
66 println!("Created product catalog:");
67 println!(" Total products: {}", product_map.len());
68 println!(" Keys: {:?}\n", product_map.keys().take(3).collect::<Vec<_>>());
69
70 let products = extract_products(&product_map);
72 println!("Extracted {} products from Arc<RwLock<Product>>\n", products.len());
73
74 println!("═══════════════════════════════════════════════════════════════");
78 println!("Lazy Operation 1: where_ (filtering)");
79 println!("═══════════════════════════════════════════════════════════════\n");
80
81 println!("Building filtered query (nothing executes yet)...");
82 let electronics_query = LazyQuery::new(&products)
83 .where_(Product::category_r(), |cat| cat == "Electronics")
84 .where_(Product::active_r(), |&active| active)
85 .where_(Product::stock_r(), |&stock| stock > 20);
86
87 println!(" ✅ Query built (deferred execution)\n");
88
89 println!("Collecting results (executes now)...");
90 let electronics: Vec<_> = electronics_query.collect();
91 println!(" Found {} electronics in stock", electronics.len());
92 for p in &electronics {
93 println!(" • {}: {} in stock", p.name, p.stock);
94 }
95
96 println!("\n═══════════════════════════════════════════════════════════════");
100 println!("Lazy Operation 2: select_lazy (projection)");
101 println!("═══════════════════════════════════════════════════════════════\n");
102
103 println!("Selecting product names (lazy)...");
104 let names: Vec<String> = LazyQuery::new(&products)
105 .where_(Product::category_r(), |cat| cat == "Furniture")
106 .select_lazy(Product::name_r())
107 .collect();
108
109 println!(" Furniture names ({}):", names.len());
110 for name in &names {
111 println!(" • {}", name);
112 }
113
114 println!("\n═══════════════════════════════════════════════════════════════");
118 println!("Lazy Operation 3: take_lazy (early termination)");
119 println!("═══════════════════════════════════════════════════════════════\n");
120
121 println!("Getting first 3 electronics...");
122 let first_3: Vec<_> = LazyQuery::new(&products)
123 .where_(Product::category_r(), |cat| cat == "Electronics")
124 .take_lazy(3)
125 .collect();
126
127 println!(" First 3 electronics:");
128 for (i, p) in first_3.iter().enumerate() {
129 println!(" {}. {} - ${:.2}", i + 1, p.name, p.price);
130 }
131 println!(" ✅ Stopped after finding 3 items!");
132
133 println!("\n═══════════════════════════════════════════════════════════════");
137 println!("Lazy Operation 4: skip_lazy (pagination)");
138 println!("═══════════════════════════════════════════════════════════════\n");
139
140 println!("Getting page 2 (skip 3, take 3)...");
141 let page_2: Vec<_> = LazyQuery::new(&products)
142 .where_(Product::active_r(), |&active| active)
143 .skip_lazy(3)
144 .take_lazy(3)
145 .collect();
146
147 println!(" Page 2 items:");
148 for (i, p) in page_2.iter().enumerate() {
149 println!(" {}. {}", i + 4, p.name);
150 }
151
152 println!("\n═══════════════════════════════════════════════════════════════");
156 println!("Lazy Operation 5: first (short-circuit)");
157 println!("═══════════════════════════════════════════════════════════════\n");
158
159 println!("Finding first expensive item (>$1000)...");
160 let expensive = LazyQuery::new(&products)
161 .where_(Product::price_r(), |&price| price > 1000.0)
162 .first();
163
164 match expensive {
165 Some(p) => println!(" Found: {} - ${:.2}", p.name, p.price),
166 None => println!(" Not found"),
167 }
168 println!(" ✅ Stopped at first match!");
169
170 println!("\n═══════════════════════════════════════════════════════════════");
174 println!("Lazy Operation 6: any (existence check)");
175 println!("═══════════════════════════════════════════════════════════════\n");
176
177 println!("Checking if any furniture exists...");
178 let has_furniture = LazyQuery::new(&products)
179 .where_(Product::category_r(), |cat| cat == "Furniture")
180 .any();
181
182 println!(" Has furniture: {}", has_furniture);
183 println!(" ✅ Stopped immediately after finding first match!");
184
185 println!("\n═══════════════════════════════════════════════════════════════");
189 println!("Lazy Operation 7: count");
190 println!("═══════════════════════════════════════════════════════════════\n");
191
192 let electronics_count = LazyQuery::new(&products)
193 .where_(Product::category_r(), |cat| cat == "Electronics")
194 .count();
195
196 println!(" Electronics count: {}", electronics_count);
197
198 println!("\n═══════════════════════════════════════════════════════════════");
202 println!("Lazy Operation 8: sum_by (aggregation)");
203 println!("═══════════════════════════════════════════════════════════════\n");
204
205 let total_value: f64 = LazyQuery::new(&products)
206 .where_(Product::category_r(), |cat| cat == "Electronics")
207 .sum_by(Product::price_r());
208
209 println!(" Total electronics value: ${:.2}", total_value);
210
211 println!("\n═══════════════════════════════════════════════════════════════");
215 println!("Lazy Operation 9: avg_by");
216 println!("═══════════════════════════════════════════════════════════════\n");
217
218 let avg_price = LazyQuery::new(&products)
219 .where_(Product::category_r(), |cat| cat == "Furniture")
220 .avg_by(Product::price_r())
221 .unwrap_or(0.0);
222
223 println!(" Average furniture price: ${:.2}", avg_price);
224
225 println!("\n═══════════════════════════════════════════════════════════════");
229 println!("Lazy Operation 10: min_by_float / max_by_float");
230 println!("═══════════════════════════════════════════════════════════════\n");
231
232 let min_price = LazyQuery::new(&products)
233 .where_(Product::active_r(), |&active| active)
234 .min_by_float(Product::price_r())
235 .unwrap_or(0.0);
236
237 let max_price = LazyQuery::new(&products)
238 .where_(Product::active_r(), |&active| active)
239 .max_by_float(Product::price_r())
240 .unwrap_or(0.0);
241
242 println!(" Price range for active products:");
243 println!(" Min: ${:.2}", min_price);
244 println!(" Max: ${:.2}", max_price);
245
246 println!("\n═══════════════════════════════════════════════════════════════");
250 println!("Lazy Operation 11: find (with predicate)");
251 println!("═══════════════════════════════════════════════════════════════\n");
252
253 let high_rated = LazyQuery::new(&products)
254 .where_(Product::category_r(), |cat| cat == "Electronics")
255 .find(|item| item.rating > 4.7);
256
257 if let Some(product) = high_rated {
258 println!(" First highly-rated electronic:");
259 println!(" {}: Rating {:.1}", product.name, product.rating);
260 }
261
262 println!("\n═══════════════════════════════════════════════════════════════");
266 println!("Lazy Operation 12: for_each (iteration)");
267 println!("═══════════════════════════════════════════════════════════════\n");
268
269 println!(" Low stock alerts:");
270 LazyQuery::new(&products)
271 .where_(Product::stock_r(), |&stock| stock < 20)
272 .for_each(|product| {
273 println!(" ⚠️ {}: Only {} in stock", product.name, product.stock);
274 });
275
276 println!("\n═══════════════════════════════════════════════════════════════");
280 println!("Lazy Operation 14: fold (custom aggregation)");
281 println!("═══════════════════════════════════════════════════════════════\n");
282
283 let total_inventory_value = LazyQuery::new(&products)
284 .where_(Product::active_r(), |&active| active)
285 .fold(0.0, |acc, product| {
286 acc + (product.price * product.stock as f64)
287 });
288
289 println!(" Total inventory value: ${:.2}", total_inventory_value);
290
291 println!("\n═══════════════════════════════════════════════════════════════");
295 println!("Lazy Operation 15: all_match (validation)");
296 println!("═══════════════════════════════════════════════════════════════\n");
297
298 let all_priced = LazyQuery::new(&products)
299 .all_match(|item| item.price > 0.0);
300
301 println!(" All products have valid prices: {}", all_priced);
302
303 println!("\n═══════════════════════════════════════════════════════════════");
307 println!("Lazy Operation 16: into_iter (for loop)");
308 println!("═══════════════════════════════════════════════════════════════\n");
309
310 println!(" High-value products (>$300):");
311 for product in LazyQuery::new(&products)
312 .where_(Product::price_r(), |&p| p > 300.0)
313 .take_lazy(5)
314 {
315 println!(" • {}: ${:.2}", product.name, product.price);
316 }
317
318 println!("\n═══════════════════════════════════════════════════════════════");
322 println!("Lazy Operation 17: map_items (transformation)");
323 println!("═══════════════════════════════════════════════════════════════\n");
324
325 let price_tags: Vec<String> = LazyQuery::new(&products)
326 .where_(Product::category_r(), |cat| cat == "Electronics")
327 .map_items(|p| format!("{}: ${:.2}", p.name, p.price))
328 .take(5)
329 .collect();
330
331 println!(" Electronics price tags:");
332 for tag in &price_tags {
333 println!(" • {}", tag);
334 }
335
336 println!("\n═══════════════════════════════════════════════════════════════");
340 println!("Complex Example: Multi-stage lazy pipeline");
341 println!("═══════════════════════════════════════════════════════════════\n");
342
343 println!("Building complex query:");
344 println!(" 1. Filter by category (Electronics)");
345 println!(" 2. Filter by price range ($50-$500)");
346 println!(" 3. Filter by rating (>4.5)");
347 println!(" 4. Select names");
348 println!(" 5. Take first 3");
349 println!();
350
351 let results: Vec<String> = LazyQuery::new(&products)
352 .where_(Product::category_r(), |cat| cat == "Electronics")
353 .where_(Product::price_r(), |&p| p >= 50.0 && p <= 500.0)
354 .where_(Product::rating_r(), |&r| r > 4.5)
355 .select_lazy(Product::name_r())
356 .take(3)
357 .collect();
358
359 println!(" Results:");
360 for (i, name) in results.iter().enumerate() {
361 println!(" {}. {}", i + 1, name);
362 }
363 println!(" ✅ All operations fused and executed lazily!");
364
365 println!("\n═══════════════════════════════════════════════════════════════");
369 println!("Bonus: Thread-safe updates with RwLock");
370 println!("═══════════════════════════════════════════════════════════════\n");
371
372 if let Some(product_arc) = product_map.get("PROD-002") {
374 println!("Updating PROD-002 stock...");
375
376 if let Ok(mut product) = product_arc.write() {
378 let old_stock = product.stock;
379 product.stock = 25;
380 println!(" Stock updated: {} → {}", old_stock, product.stock);
381 }
382 }
383
384 let updated_products = extract_products(&product_map);
386 let mouse = LazyQuery::new(&updated_products)
387 .find(|p| p.id == 2);
388
389 if let Some(product) = mouse {
390 println!(" Verified update: {} now has {} in stock", product.name, product.stock);
391 }
392
393 println!("\n═══════════════════════════════════════════════════════════════");
397 println!("Practical Example: Price analysis by category");
398 println!("═══════════════════════════════════════════════════════════════\n");
399
400 let categories = vec!["Electronics", "Furniture"];
401
402 for category in categories {
403 println!(" {} Statistics:", category);
404
405 let cat_products: Vec<Product> = products.iter()
407 .filter(|p| p.category == category)
408 .cloned()
409 .collect();
410
411 let count = LazyQuery::new(&cat_products).count();
412 let total = LazyQuery::new(&cat_products).sum_by(Product::price_r());
413 let avg = LazyQuery::new(&cat_products).avg_by(Product::price_r()).unwrap_or(0.0);
414 let min = LazyQuery::new(&cat_products).min_by_float(Product::price_r()).unwrap_or(0.0);
415 let max = LazyQuery::new(&cat_products).max_by_float(Product::price_r()).unwrap_or(0.0);
416
417 println!(" Count: {}", count);
418 println!(" Total: ${:.2}", total);
419 println!(" Average: ${:.2}", avg);
420 println!(" Range: ${:.2} - ${:.2}\n", min, max);
421 }
422
423 println!("═══════════════════════════════════════════════════════════════");
427 println!("HashMap Integration: Query by key patterns");
428 println!("═══════════════════════════════════════════════════════════════\n");
429
430 let electronics_keys: Vec<String> = product_map
432 .iter()
433 .filter(|(_key, value)| {
434 if let Ok(guard) = value.read() {
436 guard.category == "Electronics"
437 } else {
438 false
439 }
440 })
441 .map(|(key, _value)| key.clone())
442 .collect();
443
444 println!(" Electronics product IDs:");
445 for key in electronics_keys.iter().take(5) {
446 println!(" • {}", key);
447 }
448
449 println!("\n═══════════════════════════════════════════════════════════════");
453 println!("Performance: Lazy vs Eager comparison");
454 println!("═══════════════════════════════════════════════════════════════\n");
455
456 println!("Scenario: Find first product with rating > 4.7 from {} products\n", products.len());
457
458 println!(" Eager approach (hypothetical):");
459 println!(" - Filter all {} products", products.len());
460 println!(" - Collect filtered results");
461 println!(" - Take first item");
462 println!(" - Wasted work: Check all items\n");
463
464 println!(" Lazy approach (actual):");
465 let _first_rated = LazyQuery::new(&products)
466 .where_(Product::rating_r(), |&r| r > 4.7)
467 .first();
468 println!(" - Starts checking products");
469 println!(" - Stops at first match");
470 println!(" - ✅ Early termination - checks ~3-5 items only!");
471
472 println!("\n╔══════════════════════════════════════════════════════════════════╗");
476 println!("║ Summary: All Lazy Operations Demonstrated ║");
477 println!("╚══════════════════════════════════════════════════════════════════╝\n");
478
479 println!("✅ Lazy Query Operations:");
480 println!(" 1. ✅ where_ - Lazy filtering");
481 println!(" 2. ✅ select_lazy - Lazy projection");
482 println!(" 3. ✅ take_lazy - Early termination");
483 println!(" 4. ✅ skip_lazy - Pagination");
484 println!(" 5. ✅ first - Short-circuit search");
485 println!(" 6. ✅ any - Existence check (short-circuit)");
486 println!(" 7. ✅ count - Count items");
487 println!(" 8. ✅ sum_by - Sum aggregation");
488 println!(" 9. ✅ avg_by - Average aggregation");
489 println!(" 10. ✅ min_by_float - Minimum value");
490 println!(" 11. ✅ max_by_float - Maximum value");
491 println!(" 12. ✅ find - Find with predicate (short-circuit)");
492 println!(" 13. ✅ for_each - Iteration");
493 println!(" 14. ✅ fold - Custom aggregation");
494 println!(" 15. ✅ all_match - Validation (short-circuit)");
495 println!(" 16. ✅ into_iter - For loop support");
496 println!(" 17. ✅ map_items - Transformation\n");
497
498 println!("✅ Arc<RwLock<T>> Benefits:");
499 println!(" • Thread-safe shared access");
500 println!(" • Interior mutability");
501 println!(" • Multiple readers, single writer");
502 println!(" • Reference counting (Arc)");
503 println!(" • Can be queried after extracting data\n");
504
505 println!("✅ HashMap<K, Arc<RwLock<V>>> Benefits:");
506 println!(" • Fast key-based lookup");
507 println!(" • Thread-safe value access");
508 println!(" • Can query all values");
509 println!(" • Can filter by key patterns");
510 println!(" • Perfect for shared state/caches\n");
511
512 println!("🎯 Use Cases:");
513 println!(" • Shared product catalogs");
514 println!(" • User session stores");
515 println!(" • Configuration caches");
516 println!(" • Real-time inventory systems");
517 println!(" • Multi-threaded data processing");
518 println!(" • Web server state management\n");
519
520 println!("✓ Arc<RwLock<T>> HashMap with all lazy operations demo complete!\n");
521}
522