rust_queries_builder/
ext.rs

1use crate::{Query, LazyQuery};
2
3/// Extension trait that adds query methods directly to containers
4/// 
5/// This trait allows you to call query methods directly on containers:
6/// 
7/// ```ignore
8/// use rust_queries_builder::QueryExt;
9/// 
10/// let products = vec![...];
11/// let results = products.query().where_(...).all();
12/// let results = products.lazy_query().where_(...).collect();
13/// ```
14pub trait QueryExt<T> {
15    /// Create an eager Query from this container
16    fn query(&self) -> Query<T>;
17    
18    /// Create a lazy Query from this container
19    /// 
20    /// This method returns an opaque iterator type that implements all lazy query methods.
21    /// The iterator borrows from the container.
22    fn lazy_query(&self) -> LazyQuery<T, std::slice::Iter<'_, T>>;
23}
24
25// Implementations for Vec
26impl<T: 'static> QueryExt<T> for Vec<T> {
27    fn query(&self) -> Query<T> {
28        Query::new(self)
29    }
30    
31    fn lazy_query(&self) -> LazyQuery<T, std::slice::Iter<'_, T>> {
32        LazyQuery::new(self)
33    }
34}
35
36// Implementations for slices
37impl<T: 'static> QueryExt<T> for [T] {
38    fn query(&self) -> Query<T> {
39        Query::new(self)
40    }
41    
42    fn lazy_query(&self) -> LazyQuery<T, std::slice::Iter<'_, T>> {
43        LazyQuery::new(self)
44    }
45}
46
47// Array implementations
48impl<T: 'static, const N: usize> QueryExt<T> for [T; N] {
49    fn query(&self) -> Query<T> {
50        Query::new(&self[..])
51    }
52    
53    fn lazy_query(&self) -> LazyQuery<T, std::slice::Iter<'_, T>> {
54        LazyQuery::new(&self[..])
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use key_paths_derive::Keypaths;
62
63    #[derive(Debug, Clone, PartialEq, Keypaths)]
64    struct Product {
65        id: u32,
66        name: String,
67        price: f64,
68        category: String,
69    }
70
71    #[test]
72    fn test_vec_query_ext() {
73        let products = vec![
74            Product {
75                id: 1,
76                name: "Laptop".to_string(),
77                price: 999.99,
78                category: "Electronics".to_string(),
79            },
80            Product {
81                id: 2,
82                name: "Mouse".to_string(),
83                price: 29.99,
84                category: "Electronics".to_string(),
85            },
86        ];
87
88        let query = products
89            .query()
90            .where_(Product::price_r(), |&p| p > 50.0);
91        let results = query.all();
92
93        assert_eq!(results.len(), 1);
94        assert_eq!(results[0].name, "Laptop");
95    }
96
97    #[test]
98    fn test_vec_lazy_query_ext() {
99        let products = vec![
100            Product {
101                id: 1,
102                name: "Laptop".to_string(),
103                price: 999.99,
104                category: "Electronics".to_string(),
105            },
106            Product {
107                id: 2,
108                name: "Mouse".to_string(),
109                price: 29.99,
110                category: "Electronics".to_string(),
111            },
112        ];
113
114        let results: Vec<_> = products
115            .lazy_query()
116            .where_(Product::price_r(), |&p| p > 50.0)
117            .collect();
118
119        assert_eq!(results.len(), 1);
120        assert_eq!(results[0].name, "Laptop");
121    }
122
123    #[test]
124    fn test_array_query_ext() {
125        let products = [
126            Product {
127                id: 1,
128                name: "Laptop".to_string(),
129                price: 999.99,
130                category: "Electronics".to_string(),
131            },
132            Product {
133                id: 2,
134                name: "Mouse".to_string(),
135                price: 29.99,
136                category: "Electronics".to_string(),
137            },
138        ];
139
140        let results: Vec<_> = products
141            .lazy_query()
142            .where_(Product::price_r(), |&p| p < 100.0)
143            .collect();
144
145        assert_eq!(results.len(), 1);
146        assert_eq!(results[0].name, "Mouse");
147    }
148
149    #[test]
150    fn test_slice_query_ext() {
151        let products = vec![
152            Product {
153                id: 1,
154                name: "Laptop".to_string(),
155                price: 999.99,
156                category: "Electronics".to_string(),
157            },
158            Product {
159                id: 2,
160                name: "Mouse".to_string(),
161                price: 29.99,
162                category: "Electronics".to_string(),
163            },
164        ];
165
166        let slice = &products[..];
167        let query = slice
168            .query()
169            .where_(Product::category_r(), |cat| cat == "Electronics");
170        let results = query.count();
171
172        assert_eq!(results, 2);
173    }
174}