QueryWithSkip

Struct QueryWithSkip 

Source
pub struct QueryWithSkip<'a, 'b, T>
where T: 'static,
{ /* private fields */ }
Expand description

Helper struct for pagination after a skip operation.

Created by calling skip() on a Query.

Implementations§

Source§

impl<'a, 'b, T> QueryWithSkip<'a, 'b, T>
where T: 'static,

Source

pub fn limit(&self, n: usize) -> Vec<&'a T>

Returns up to n items after skipping the offset.

§Arguments
  • n - The maximum number of items to return
§Example
let page_2 = query.skip(20).limit(10);
Examples found in repository?
examples/without_clone.rs (line 133)
28fn main() {
29    println!("╔════════════════════════════════════════════════════════════╗");
30    println!("║  Query Builder Without Clone - Performance Optimization   ║");
31    println!("╚════════════════════════════════════════════════════════════╝\n");
32
33    let employees = vec![
34        Employee {
35            id: 1,
36            name: "Alice".to_string(),
37            email: "alice@example.com".to_string(),
38            department: "Engineering".to_string(),
39            salary: 95000.0,
40            large_data: vec![0; 1000], // Large data - expensive to clone!
41        },
42        Employee {
43            id: 2,
44            name: "Bob".to_string(),
45            email: "bob@example.com".to_string(),
46            department: "Engineering".to_string(),
47            salary: 87000.0,
48            large_data: vec![0; 1000],
49        },
50        Employee {
51            id: 3,
52            name: "Carol".to_string(),
53            email: "carol@example.com".to_string(),
54            department: "Sales".to_string(),
55            salary: 75000.0,
56            large_data: vec![0; 1000],
57        },
58    ];
59
60    let departments = vec![
61        Department {
62            id: 1,
63            name: "Engineering".to_string(),
64            budget: 1000000.0,
65        },
66        Department {
67            id: 2,
68            name: "Sales".to_string(),
69            budget: 500000.0,
70        },
71    ];
72
73    println!("✅ Operations that DON'T require Clone:\n");
74
75    // 1. WHERE filtering - returns Vec<&T>
76    println!("1. WHERE filtering (returns references)");
77    let query = Query::new(&employees)
78        .where_(Employee::department_r(), |dept| dept == "Engineering");
79    let engineering = query.all();
80    println!("   Found {} engineering employees", engineering.len());
81    for emp in &engineering {
82        println!("     - {}: ${:.0}", emp.name, emp.salary);
83    }
84
85    // 2. COUNT - no cloning needed
86    println!("\n2. COUNT aggregation");
87    let count = Query::new(&employees)
88        .where_(Employee::salary_r(), |&sal| sal > 80000.0)
89        .count();
90    println!("   {} employees earn over $80k", count);
91
92    // 3. SELECT - only clones the selected field
93    println!("\n3. SELECT (only selected fields are cloned)");
94    let names: Vec<String> = Query::new(&employees)
95        .select(Employee::name_r());
96    println!("   Employee names: {:?}", names);
97
98    // 4. FIRST - returns Option<&T>
99    println!("\n4. FIRST (returns reference)");
100    let query = Query::new(&employees)
101        .where_(Employee::salary_r(), |&sal| sal > 90000.0);
102    if let Some(emp) = query.first() {
103        println!("   First high earner: {} (${:.0})", emp.name, emp.salary);
104    }
105
106    // 5. SUM/AVG aggregations - no cloning
107    println!("\n5. Aggregations (SUM/AVG)");
108    let eng_query = Query::new(&employees)
109        .where_(Employee::department_r(), |dept| dept == "Engineering");
110    let total = eng_query.sum(Employee::salary_r());
111    let avg = eng_query.avg(Employee::salary_r()).unwrap_or(0.0);
112    println!("   Engineering total: ${:.0}", total);
113    println!("   Engineering average: ${:.0}", avg);
114
115    // 6. MIN/MAX - no cloning
116    println!("\n6. MIN/MAX");
117    let min = Query::new(&employees).min_float(Employee::salary_r());
118    let max = Query::new(&employees).max_float(Employee::salary_r());
119    println!("   Salary range: ${:.0} - ${:.0}", min.unwrap(), max.unwrap());
120
121    // 7. LIMIT - returns Vec<&T>
122    println!("\n7. LIMIT (returns references)");
123    let query = Query::new(&employees);
124    let first_two = query.limit(2);
125    println!("   First 2 employees:");
126    for emp in &first_two {
127        println!("     - {}", emp.name);
128    }
129
130    // 8. SKIP/Pagination - returns Vec<&T>
131    println!("\n8. SKIP/Pagination (returns references)");
132    let query = Query::new(&employees);
133    let page_2 = query.skip(2).limit(1);
134    println!("   Page 2:");
135    for emp in &page_2 {
136        println!("     - {}", emp.name);
137    }
138
139    // 9. EXISTS - just checks
140    println!("\n9. EXISTS check");
141    let has_sales = Query::new(&employees)
142        .where_(Employee::department_r(), |dept| dept == "Sales")
143        .exists();
144    println!("   Has Sales employees: {}", has_sales);
145
146    // 10. JOIN - no Clone required on L or R!
147    println!("\n10. JOIN operations (no Clone required!)");
148    let results = JoinQuery::new(&employees, &departments)
149        .inner_join(
150            Employee::department_r(),
151            Department::name_r(),
152            |emp, dept| {
153                // Mapper only clones what it needs for the result
154                (emp.name.clone(), dept.budget)
155            },
156        );
157    println!("   Employee-Department pairs:");
158    for (name, budget) in &results {
159        println!("     - {} works in dept with ${:.0} budget", name, budget);
160    }
161
162    println!("\n╔════════════════════════════════════════════════════════════╗");
163    println!("║  Operations that REQUIRE Clone (only when needed)         ║");
164    println!("╚════════════════════════════════════════════════════════════╝\n");
165
166    println!("⚠️  The following operations require Clone because they return owned Vec<T>:");
167    println!("   - order_by() / order_by_desc()");
168    println!("   - order_by_float() / order_by_float_desc()");
169    println!("   - group_by()");
170    println!("\n   To use these, add #[derive(Clone)] to your struct:");
171    println!("   ```rust");
172    println!("   #[derive(Clone, Keypaths)]  // Add Clone here");
173    println!("   struct Employee {{ ... }}");
174    println!("   ```");
175
176    println!("\n╔════════════════════════════════════════════════════════════╗");
177    println!("║  Performance Benefits                                      ║");
178    println!("╚════════════════════════════════════════════════════════════╝\n");
179
180    println!("✅ Zero cloning for most operations");
181    println!("✅ Work with large structs efficiently");
182    println!("✅ No unnecessary memory allocations");
183    println!("✅ Only clone when you actually need owned data");
184    println!("✅ Pay for what you use");
185
186    println!("\n✓ Example complete! Most operations work without Clone.\n");
187}
More examples
Hide additional examples
examples/doc_examples.rs (line 132)
30fn main() {
31    println!("Testing documentation examples...\n");
32
33    // Example from README - Quick Start
34    println!("Test 1: README Quick Start Example");
35    {
36        let products = vec![
37            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
38            Product { id: 2, name: "Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.0 },
39            Product { id: 3, name: "Desk".to_string(), price: 299.99, category: "Furniture".to_string(), stock: 10, rating: 4.8 },
40        ];
41
42        let affordable_query = Query::new(&products)
43            .where_(Product::category_r(), |cat| cat == "Electronics")
44            .where_(Product::price_r(), |&price| price < 100.0);
45        let affordable_electronics = affordable_query.all();
46
47        println!("  Found {} affordable electronics ✅", affordable_electronics.len());
48    }
49
50    // Example from README - Filtering
51    println!("\nTest 2: Filtering Example");
52    {
53        let products = vec![
54            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
55        ];
56
57        let electronics_query = Query::new(&products)
58            .where_(Product::category_r(), |cat| cat == "Electronics");
59        let electronics = electronics_query.all();
60
61        println!("  Found {} electronics ✅", electronics.len());
62    }
63
64    // Example from README - Selecting
65    println!("\nTest 3: Selecting Fields Example");
66    {
67        let products = vec![
68            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
69            Product { id: 2, name: "Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.0 },
70        ];
71
72        let names: Vec<String> = Query::new(&products)
73            .select(Product::name_r());
74
75        println!("  Selected {} names ✅", names.len());
76    }
77
78    // Example from README - Ordering
79    println!("\nTest 4: Ordering Example");
80    {
81        let products = vec![
82            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
83            Product { id: 2, name: "Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.0 },
84        ];
85
86        let by_price = Query::new(&products).order_by_float(Product::price_r());
87        println!("  Ordered {} products ✅", by_price.len());
88    }
89
90    // Example from README - Aggregations
91    println!("\nTest 5: Aggregations Example");
92    {
93        let products = vec![
94            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
95            Product { id: 2, name: "Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.0 },
96        ];
97
98        let electronics_query = Query::new(&products)
99            .where_(Product::category_r(), |cat| cat == "Electronics");
100
101        let count = electronics_query.count();
102        let total_value: f64 = electronics_query.sum(Product::price_r());
103        let avg_price = electronics_query.avg(Product::price_r()).unwrap_or(0.0);
104
105        println!("  Count: {}, Total: ${:.2}, Avg: ${:.2} ✅", count, total_value, avg_price);
106    }
107
108    // Example from README - Grouping
109    println!("\nTest 6: Grouping Example");
110    {
111        let products = vec![
112            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
113            Product { id: 2, name: "Mouse".to_string(), price: 29.99, category: "Electronics".to_string(), stock: 50, rating: 4.0 },
114            Product { id: 3, name: "Desk".to_string(), price: 299.99, category: "Furniture".to_string(), stock: 10, rating: 4.8 },
115        ];
116
117        let by_category = Query::new(&products).group_by(Product::category_r());
118        println!("  Grouped into {} categories ✅", by_category.len());
119    }
120
121    // Example from README - Pagination
122    println!("\nTest 7: Pagination Example");
123    {
124        let products = vec![
125            Product { id: 1, name: "P1".to_string(), price: 10.0, category: "A".to_string(), stock: 1, rating: 4.0 },
126            Product { id: 2, name: "P2".to_string(), price: 20.0, category: "A".to_string(), stock: 1, rating: 4.0 },
127            Product { id: 3, name: "P3".to_string(), price: 30.0, category: "A".to_string(), stock: 1, rating: 4.0 },
128        ];
129
130        let query = Query::new(&products);
131        let first_10 = query.limit(10);
132        let page_1 = query.skip(0).limit(10);
133
134        println!("  Limited to {} products ✅", first_10.len());
135        println!("  Page 1 has {} products ✅", page_1.len());
136    }
137
138    // Example from README - Join
139    println!("\nTest 8: Join Example");
140    {
141        let users = vec![
142            User { id: 1, name: "Alice".to_string() },
143            User { id: 2, name: "Bob".to_string() },
144        ];
145
146        let orders = vec![
147            Order { id: 101, user_id: 1, total: 99.99 },
148            Order { id: 102, user_id: 1, total: 149.99 },
149        ];
150
151        let user_orders = JoinQuery::new(&users, &orders).inner_join(
152            User::id_r(),
153            Order::user_id_r(),
154            |user, order| (user.name.clone(), order.total),
155        );
156
157        println!("  Joined {} user-order pairs ✅", user_orders.len());
158    }
159
160    // Example from SQL_COMPARISON - SELECT with WHERE
161    println!("\nTest 9: SQL Comparison - SELECT with WHERE");
162    {
163        #[derive(Clone, Keypaths)]
164        struct Employee {
165            department: String,
166        }
167
168        let employees = vec![
169            Employee { department: "Engineering".to_string() },
170            Employee { department: "Sales".to_string() },
171        ];
172
173        let engineering_query = Query::new(&employees)
174            .where_(Employee::department_r(), |dept| dept == "Engineering");
175        let engineering = engineering_query.all();
176
177        println!("  Found {} engineering employees ✅", engineering.len());
178    }
179
180    // Example from USAGE.md - Complex Filtering
181    println!("\nTest 10: USAGE - Complex Filtering");
182    {
183        let products = vec![
184            Product { id: 1, name: "Laptop".to_string(), price: 999.99, category: "Electronics".to_string(), stock: 15, rating: 4.5 },
185        ];
186
187        let results_query = Query::new(&products)
188            .where_(Product::category_r(), |cat| cat == "Electronics")
189            .where_(Product::price_r(), |&price| price >= 100.0 && price <= 500.0)
190            .where_(Product::stock_r(), |&stock| stock > 10);
191        let results = results_query.order_by_float(Product::price_r());
192
193        println!("  Filtered {} products ✅", results.len());
194    }
195
196    println!("\n✅ All documentation examples compile and run successfully!");
197}
examples/advanced_query_builder.rs (line 185)
110fn main() {
111    println!("=== Advanced Query Builder Demo ===\n");
112
113    let products = create_product_catalog();
114    println!("Total products in catalog: {}\n", products.len());
115
116    // Query 1: Select all product names
117    println!("--- Query 1: Select All Product Names ---");
118    let names = Query::new(&products).select(Product::name_r());
119    println!("Product names ({}):", names.len());
120    for name in &names {
121        println!("  • {}", name);
122    }
123
124    // Query 2: Order by price (ascending)
125    println!("\n--- Query 2: Products Ordered by Price (Ascending) ---");
126    let ordered = Query::new(&products).order_by_float(Product::price_r());
127    for product in ordered.iter().take(5) {
128        println!("  • {} - ${:.2}", product.name, product.price);
129    }
130
131    // Query 3: Order by rating (descending)
132    println!("\n--- Query 3: Top-Rated Products (Descending) ---");
133    let top_rated = Query::new(&products).order_by_float_desc(Product::rating_r());
134    for product in top_rated.iter().take(5) {
135        println!("  • {} - Rating: {:.1}", product.name, product.rating);
136    }
137
138    // Query 4: Group by category
139    println!("\n--- Query 4: Products Grouped by Category ---");
140    let by_category = Query::new(&products).group_by(Product::category_r());
141    for (category, items) in &by_category {
142        println!("  {}: {} products", category, items.len());
143        for item in items {
144            println!("    - {} (${:.2})", item.name, item.price);
145        }
146    }
147
148    // Query 5: Aggregations - Electronics statistics
149    println!("\n--- Query 5: Electronics Category Statistics ---");
150    let electronics_query = Query::new(&products)
151        .where_(Product::category_r(), |cat| cat == "Electronics");
152
153    println!("  Count: {}", electronics_query.count());
154    println!("  Total Value: ${:.2}", electronics_query.sum(Product::price_r()));
155    println!("  Average Price: ${:.2}", electronics_query.avg(Product::price_r()).unwrap_or(0.0));
156    println!("  Min Price: ${:.2}", electronics_query.min_float(Product::price_r()).unwrap_or(0.0));
157    println!("  Max Price: ${:.2}", electronics_query.max_float(Product::price_r()).unwrap_or(0.0));
158    println!("  Total Stock: {}", electronics_query.sum(Product::stock_r()));
159
160    // Query 6: Complex filtering with ordering
161    println!("\n--- Query 6: Electronics Under $200, Ordered by Rating ---");
162    let affordable_electronics = Query::new(&products)
163        .where_(Product::category_r(), |cat| cat == "Electronics")
164        .where_(Product::price_r(), |&price| price < 200.0)
165        .order_by_float_desc(Product::rating_r());
166
167    for product in &affordable_electronics {
168        println!(
169            "  • {} - ${:.2} - Rating: {:.1}",
170            product.name, product.price, product.rating
171        );
172    }
173
174    // Query 7: Limit results
175    println!("\n--- Query 7: First 3 Products ---");
176    let query7 = Query::new(&products);
177    let first_three = query7.limit(3);
178    for product in &first_three {
179        println!("  • {} (ID: {})", product.name, product.id);
180    }
181
182    // Query 8: Pagination
183    println!("\n--- Query 8: Pagination (Page 2, 3 items per page) ---");
184    let query8 = Query::new(&products);
185    let page_2 = query8.skip(3).limit(3);
186    for product in &page_2 {
187        println!("  • {} (ID: {})", product.name, product.id);
188    }
189
190    // Query 9: First matching item
191    println!("\n--- Query 9: Find First Product Over $1000 ---");
192    let query9 = Query::new(&products)
193        .where_(Product::price_r(), |&price| price > 1000.0);
194    let expensive = query9.first();
195
196    if let Some(product) = expensive {
197        println!("  Found: {} - ${:.2}", product.name, product.price);
198    } else {
199        println!("  No products found over $1000");
200    }
201
202    // Query 10: Check existence
203    println!("\n--- Query 10: Check if Any Furniture Exists ---");
204    let has_furniture = Query::new(&products)
205        .where_(Product::category_r(), |cat| cat == "Furniture")
206        .exists();
207    println!("  Furniture available: {}", has_furniture);
208
209    // Query 11: Multiple aggregations by group
210    println!("\n--- Query 11: Category Statistics ---");
211    let grouped = Query::new(&products).group_by(Product::category_r());
212
213    for (category, items) in &grouped {
214        let cat_query = Query::new(items);
215        println!("\n  {} Statistics:", category);
216        println!("    Products: {}", items.len());
217        println!("    Total Value: ${:.2}", cat_query.sum(Product::price_r()));
218        println!("    Avg Price: ${:.2}", cat_query.avg(Product::price_r()).unwrap_or(0.0));
219        println!("    Total Stock: {}", cat_query.sum(Product::stock_r()));
220        println!("    Avg Rating: {:.2}", cat_query.avg(Product::rating_r()).unwrap_or(0.0));
221    }
222
223    // Query 12: Complex multi-stage query
224    println!("\n--- Query 12: Top 3 Highly-Rated Products (Rating > 4.5) by Price ---");
225    let top_products = Query::new(&products)
226        .where_(Product::rating_r(), |&rating| rating > 4.5)
227        .order_by_float_desc(Product::price_r());
228
229    for (i, product) in top_products.iter().take(3).enumerate() {
230        println!(
231            "  {}. {} - ${:.2} - Rating: {:.1}",
232            i + 1,
233            product.name,
234            product.price,
235            product.rating
236        );
237    }
238
239    // Query 13: Select multiple fields (simulated with tuples)
240    println!("\n--- Query 13: Select Name and Price for Electronics ---");
241    let query13 = Query::new(&products)
242        .where_(Product::category_r(), |cat| cat == "Electronics");
243    let electronics = query13.all();
244
245    for product in electronics {
246        println!("  • {} - ${:.2}", product.name, product.price);
247    }
248
249    // Query 14: Stock analysis
250    println!("\n--- Query 14: Low Stock Alert (Stock < 20) ---");
251    let low_stock = Query::new(&products)
252        .where_(Product::stock_r(), |&stock| stock < 20)
253        .order_by(Product::stock_r());
254
255    for product in &low_stock {
256        println!("  ⚠️  {} - Only {} in stock", product.name, product.stock);
257    }
258
259    // Query 15: Price range query with multiple conditions
260    println!("\n--- Query 15: Mid-Range Products ($50-$300) with Good Ratings (>4.5) ---");
261    let mid_range = Query::new(&products)
262        .where_(Product::price_r(), |&price| price >= 50.0 && price <= 300.0)
263        .where_(Product::rating_r(), |&rating| rating > 4.5)
264        .order_by_float(Product::price_r());
265
266    for product in &mid_range {
267        println!(
268            "  • {} - ${:.2} - Rating: {:.1} - Stock: {}",
269            product.name, product.price, product.rating, product.stock
270        );
271    }
272
273    // Query 16: Revenue calculation
274    println!("\n--- Query 16: Potential Revenue by Category ---");
275    let by_category = Query::new(&products).group_by(Product::category_r());
276
277    for (category, items) in &by_category {
278        let revenue: f64 = items.iter().map(|p| p.price * p.stock as f64).sum();
279        println!("  {}: ${:.2}", category, revenue);
280    }
281
282    println!("\n✓ Advanced query builder demo complete!");
283}

Auto Trait Implementations§

§

impl<'a, 'b, T> Freeze for QueryWithSkip<'a, 'b, T>

§

impl<'a, 'b, T> !RefUnwindSafe for QueryWithSkip<'a, 'b, T>

§

impl<'a, 'b, T> !Send for QueryWithSkip<'a, 'b, T>

§

impl<'a, 'b, T> !Sync for QueryWithSkip<'a, 'b, T>

§

impl<'a, 'b, T> Unpin for QueryWithSkip<'a, 'b, T>

§

impl<'a, 'b, T> !UnwindSafe for QueryWithSkip<'a, 'b, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.