vantage_mongodb/select/
builder.rs1use bson::Document;
5
6use super::MongoSelect;
7
8impl MongoSelect {
9 pub async fn build_filter(&self) -> vantage_core::Result<Document> {
11 crate::condition::resolve_conditions(self.conditions.iter()).await
12 }
13
14 pub fn build_projection(&self) -> Option<Document> {
16 if self.fields.is_empty() {
17 return None;
18 }
19 let mut proj = Document::new();
20 for f in &self.fields {
21 proj.insert(f.as_str(), 1);
22 }
23 Some(proj)
24 }
25
26 pub fn build_sort(&self) -> Option<Document> {
28 if self.sort.is_empty() {
29 return None;
30 }
31 let mut doc = Document::new();
32 for (field, dir) in &self.sort {
33 doc.insert(field.as_str(), *dir);
34 }
35 Some(doc)
36 }
37
38 pub fn build_find_options(&self) -> mongodb::options::FindOptions {
40 let mut opts = mongodb::options::FindOptions::default();
41 opts.projection = self.build_projection();
42 opts.sort = self.build_sort();
43 opts.limit = self.limit;
44 opts.skip = self.skip.map(|s| s as u64);
45 opts
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use bson::doc;
52
53 use super::*;
54 use vantage_expressions::Selectable;
55
56 #[test]
57 fn test_build_projection() {
58 let s = MongoSelect::new().with_field("name").with_field("price");
59 let proj = s.build_projection().unwrap();
60 assert_eq!(proj, doc! { "name": 1, "price": 1 });
61 }
62
63 #[test]
64 fn test_build_projection_empty() {
65 let s = MongoSelect::new();
66 assert!(s.build_projection().is_none());
67 }
68
69 #[test]
70 fn test_build_sort() {
71 let mut s = MongoSelect::new();
72 s.sort.push(("price".into(), 1));
73 s.sort.push(("name".into(), -1));
74 let sort = s.build_sort().unwrap();
75 assert_eq!(sort, doc! { "price": 1, "name": -1 });
76 }
77
78 #[test]
79 fn test_build_find_options() {
80 let s = MongoSelect::new()
81 .with_field("name")
82 .with_limit(Some(5), Some(10));
83 let opts = s.build_find_options();
84 assert!(opts.projection.is_some());
85 assert_eq!(opts.limit, Some(5));
86 assert_eq!(opts.skip, Some(10));
87 }
88
89 #[tokio::test]
90 async fn test_build_filter_empty() {
91 let s = MongoSelect::new();
92 let filter = s.build_filter().await.unwrap();
93 assert_eq!(filter, doc! {});
94 }
95
96 #[tokio::test]
97 async fn test_build_filter_single() {
98 let s = MongoSelect::new().with_condition(doc! { "active": true });
99 let filter = s.build_filter().await.unwrap();
100 assert_eq!(filter, doc! { "active": true });
101 }
102
103 #[tokio::test]
104 async fn test_build_filter_multiple() {
105 let s = MongoSelect::new()
106 .with_condition(doc! { "active": true })
107 .with_condition(doc! { "price": { "$gt": 100 } });
108 let filter = s.build_filter().await.unwrap();
109 assert_eq!(
110 filter,
111 doc! { "$and": [{ "active": true }, { "price": { "$gt": 100 } }] }
112 );
113 }
114}