container_support/
container_support.rs

1// Demonstrates support for various container types
2// Shows how to query Vec, HashMap, HashSet, BTreeMap, VecDeque, etc.
3// cargo run --example container_support
4
5use rust_queries_builder::{Query, LazyQuery};
6use key_paths_derive::Keypaths;
7use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet, VecDeque, LinkedList};
8
9#[derive(Debug, Clone, Keypaths, PartialEq, Eq, Hash, PartialOrd, Ord)]
10struct Product {
11    id: u32,
12    name: String,
13    price: u32, // Using u32 for Hash/Ord
14    category: String,
15}
16
17fn create_sample_product(id: u32, name: &str, price: u32, category: &str) -> Product {
18    Product {
19        id,
20        name: name.to_string(),
21        price,
22        category: category.to_string(),
23    }
24}
25
26fn main() {
27    println!("\n╔════════════════════════════════════════════════════════════════╗");
28    println!("║  Container Support Demo                                       ║");
29    println!("║  Query various collection types                               ║");
30    println!("╚════════════════════════════════════════════════════════════════╝\n");
31
32    // ============================================================================
33    // CONTAINER 1: Vec<T>
34    // ============================================================================
35    println!("═══════════════════════════════════════════════════════════════");
36    println!("Container 1: Vec<T>");
37    println!("═══════════════════════════════════════════════════════════════\n");
38
39    let vec_products = vec![
40        create_sample_product(1, "Laptop", 999, "Electronics"),
41        create_sample_product(2, "Mouse", 29, "Electronics"),
42        create_sample_product(3, "Desk", 299, "Furniture"),
43    ];
44
45    // Query Vec directly
46    let vec_query = Query::new(&vec_products)
47        .where_(Product::category_r(), |cat| cat == "Electronics");
48    let vec_results = vec_query.all();
49    println!("  Vec: Found {} electronics", vec_results.len());
50
51    // Lazy query on Vec
52    let lazy_count = LazyQuery::new(&vec_products)
53        .where_(Product::price_r(), |&p| p < 100)
54        .count();
55    println!("  Vec (lazy): {} items under $100", lazy_count);
56
57    // ============================================================================
58    // CONTAINER 2: VecDeque<T>
59    // ============================================================================
60    println!("\n═══════════════════════════════════════════════════════════════");
61    println!("Container 2: VecDeque<T>");
62    println!("═══════════════════════════════════════════════════════════════\n");
63
64    let mut deque_products = VecDeque::new();
65    deque_products.push_back(create_sample_product(1, "Keyboard", 129, "Electronics"));
66    deque_products.push_back(create_sample_product(2, "Monitor", 349, "Electronics"));
67    deque_products.push_back(create_sample_product(3, "Chair", 199, "Furniture"));
68
69    // Convert to owned Vec for querying
70    let deque_vec: Vec<Product> = deque_products.iter().cloned().collect();
71    let deque_query = Query::new(&deque_vec);
72    let deque_count = deque_query.count();
73    println!("  VecDeque: {} total items", deque_count);
74
75    // More efficient: use make_contiguous for zero-copy slice access
76    let contiguous = deque_products.make_contiguous();
77    let contiguous_query = Query::new(contiguous);
78    println!("  VecDeque (zero-copy): {} items", contiguous_query.count());
79
80    // ============================================================================
81    // CONTAINER 3: HashSet<T>
82    // ============================================================================
83    println!("\n═══════════════════════════════════════════════════════════════");
84    println!("Container 3: HashSet<T>");
85    println!("═══════════════════════════════════════════════════════════════\n");
86
87    let mut set_products = HashSet::new();
88    set_products.insert(create_sample_product(1, "Tablet", 499, "Electronics"));
89    set_products.insert(create_sample_product(2, "Phone", 799, "Electronics"));
90    set_products.insert(create_sample_product(3, "Lamp", 39, "Furniture"));
91
92    // Collect from HashSet to Vec for querying
93    let set_vec: Vec<Product> = set_products.iter().cloned().collect();
94    let set_query = Query::new(&set_vec)
95        .where_(Product::price_r(), |&p| p > 500);
96    let expensive = set_query.all();
97    println!("  HashSet: {} expensive items", expensive.len());
98
99    // Lazy on HashSet (convert to owned Vec first)
100    let set_owned: Vec<Product> = set_products.iter().cloned().collect();
101    let lazy_set: Vec<_> = LazyQuery::new(&set_owned)
102        .where_(Product::category_r(), |cat| cat == "Electronics")
103        .collect();
104    println!("  HashSet (lazy): {} electronics", lazy_set.len());
105
106    // ============================================================================
107    // CONTAINER 4: BTreeSet<T>
108    // ============================================================================
109    println!("\n═══════════════════════════════════════════════════════════════");
110    println!("Container 4: BTreeSet<T>");
111    println!("═══════════════════════════════════════════════════════════════\n");
112
113    let mut btree_set = BTreeSet::new();
114    btree_set.insert(create_sample_product(1, "Webcam", 79, "Electronics"));
115    btree_set.insert(create_sample_product(2, "Microphone", 129, "Electronics"));
116    btree_set.insert(create_sample_product(3, "Bookshelf", 149, "Furniture"));
117
118    let btree_vec: Vec<Product> = btree_set.iter().cloned().collect();
119    let btree_query = Query::new(&btree_vec);
120    println!("  BTreeSet: {} total items (sorted order!)", btree_query.count());
121    
122    // BTreeSet items are in sorted order
123    for (i, item) in btree_vec.iter().take(3).enumerate() {
124        println!("    {}. {} (ID: {})", i + 1, item.name, item.id);
125    }
126
127    // ============================================================================
128    // CONTAINER 5: HashMap<K, V> - Query Values
129    // ============================================================================
130    println!("\n═══════════════════════════════════════════════════════════════");
131    println!("Container 5: HashMap<K, V> - Querying values");
132    println!("═══════════════════════════════════════════════════════════════\n");
133
134    let mut map_products = HashMap::new();
135    map_products.insert("prod1", create_sample_product(1, "Speaker", 199, "Electronics"));
136    map_products.insert("prod2", create_sample_product(2, "Headphones", 149, "Electronics"));
137    map_products.insert("prod3", create_sample_product(3, "Ottoman", 249, "Furniture"));
138
139    // Query HashMap values (convert to owned Vec)
140    let map_vec: Vec<Product> = map_products.values().cloned().collect();
141    let map_query = Query::new(&map_vec)
142        .where_(Product::category_r(), |cat| cat == "Electronics");
143    let electronics = map_query.all();
144    println!("  HashMap: {} electronics", electronics.len());
145
146    // ============================================================================
147    // CONTAINER 6: BTreeMap<K, V> - Query Values
148    // ============================================================================
149    println!("\n═══════════════════════════════════════════════════════════════");
150    println!("Container 6: BTreeMap<K, V> - Querying values");
151    println!("═══════════════════════════════════════════════════════════════\n");
152
153    let mut btree_map = BTreeMap::new();
154    btree_map.insert(1, create_sample_product(1, "Router", 89, "Electronics"));
155    btree_map.insert(2, create_sample_product(2, "Switch", 129, "Electronics"));
156    btree_map.insert(3, create_sample_product(3, "Sofa", 899, "Furniture"));
157
158    let btree_map_vec: Vec<Product> = btree_map.values().cloned().collect();
159    let btree_map_query = Query::new(&btree_map_vec);
160    let avg_price = btree_map_query.sum(Product::price_r()) as f64 / btree_map.len() as f64;
161    println!("  BTreeMap: Average price ${:.2}", avg_price);
162
163    // ============================================================================
164    // CONTAINER 7: Arrays [T; N]
165    // ============================================================================
166    println!("\n═══════════════════════════════════════════════════════════════");
167    println!("Container 7: Arrays [T; N]");
168    println!("═══════════════════════════════════════════════════════════════\n");
169
170    let array_products = [
171        create_sample_product(1, "USB Cable", 15, "Electronics"),
172        create_sample_product(2, "HDMI Cable", 25, "Electronics"),
173        create_sample_product(3, "Power Strip", 35, "Electronics"),
174    ];
175
176    // Query array directly (as slice)
177    let array_query = Query::new(&array_products);
178    let total = array_query.sum(Product::price_r());
179    println!("  Array: Total value ${}", total);
180
181    // Lazy on array
182    let lazy_array: Vec<_> = LazyQuery::new(&array_products)
183        .where_(Product::price_r(), |&p| p > 20)
184        .collect();
185    println!("  Array (lazy): {} items over $20", lazy_array.len());
186
187    // ============================================================================
188    // CONTAINER 8: LinkedList<T>
189    // ============================================================================
190    println!("\n═══════════════════════════════════════════════════════════════");
191    println!("Container 8: LinkedList<T>");
192    println!("═══════════════════════════════════════════════════════════════\n");
193
194    let mut list_products = LinkedList::new();
195    list_products.push_back(create_sample_product(1, "SSD", 159, "Electronics"));
196    list_products.push_back(create_sample_product(2, "HDD", 79, "Electronics"));
197
198    let list_vec: Vec<Product> = list_products.iter().cloned().collect();
199    let list_query = Query::new(&list_vec);
200    println!("  LinkedList: {} items", list_query.count());
201
202    // ============================================================================
203    // CONTAINER 9: Option<T> and Result<T, E>
204    // ============================================================================
205    println!("\n═══════════════════════════════════════════════════════════════");
206    println!("Container 9: Option<T> and Result<T, E>");
207    println!("═══════════════════════════════════════════════════════════════\n");
208
209    let maybe_product = Some(create_sample_product(1, "Mystery Box", 99, "Special"));
210    
211    if let Some(ref product) = maybe_product {
212        let option_query = Query::new(std::slice::from_ref(product));
213        println!("  Option (Some): {} items", option_query.count());
214    }
215
216    let none_product: Option<Product> = None;
217    let none_count = none_product.iter().count();
218    println!("  Option (None): {} items", none_count);
219
220    // ============================================================================
221    // Summary
222    // ============================================================================
223    println!("\n╔════════════════════════════════════════════════════════════════╗");
224    println!("║  Supported Containers Summary                                  ║");
225    println!("╚════════════════════════════════════════════════════════════════╝\n");
226
227    println!("✅ Supported container types:");
228    println!("   • Vec<T>              - Standard vector");
229    println!("   • &[T]                - Slices");
230    println!("   • [T; N]              - Fixed-size arrays");
231    println!("   • VecDeque<T>         - Double-ended queue");
232    println!("   • LinkedList<T>       - Doubly-linked list");
233    println!("   • HashSet<T>          - Unordered set");
234    println!("   • BTreeSet<T>         - Ordered set");
235    println!("   • HashMap<K, V>       - Query values");
236    println!("   • BTreeMap<K, V>      - Query values (sorted)");
237    println!("   • Option<T>           - 0 or 1 item");
238    println!("   • Result<T, E>        - 0 or 1 item\n");
239
240    println!("📝 Usage patterns:");
241    println!("   • Direct: Query::new(&container) for Vec, slices, arrays");
242    println!("   • Convert: Collect to Vec for Sets and Maps");
243    println!("   • Lazy: LazyQuery::new(&slice) for any slice\n");
244
245    println!("💡 Tips:");
246    println!("   • Vec/slice: Direct support, most efficient");
247    println!("   • Sets: Iterate to Vec, then query");
248    println!("   • Maps: Use .values().collect() to query values");
249    println!("   • VecDeque: Use .as_slices() for zero-copy");
250    println!("   • For custom types: Implement Queryable trait\n");
251
252    println!("✓ Container support demo complete!\n");
253}
254