Skip to main content

vantage_mongodb/select/
builder.rs

1//! Builder methods for MongoSelect — produce native MongoDB types
2//! (filter Document, projection Document, sort Document, FindOptions).
3
4use bson::Document;
5
6use super::MongoSelect;
7
8impl MongoSelect {
9    /// Build the filter `Document` by resolving all conditions.
10    pub async fn build_filter(&self) -> vantage_core::Result<Document> {
11        crate::condition::resolve_conditions(self.conditions.iter()).await
12    }
13
14    /// Build the projection `Document`. Returns `None` if all fields requested.
15    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    /// Build the sort `Document`. Returns `None` if no ordering.
27    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    /// Build `mongodb::options::FindOptions` from the current state. A
39    /// positive limit is also the batch size, so a page arrives in one
40    /// round trip instead of the server's default first batch plus `getMore`s.
41    pub fn build_find_options(&self) -> mongodb::options::FindOptions {
42        let mut opts = mongodb::options::FindOptions::default();
43        opts.projection = self.build_projection();
44        opts.sort = self.build_sort();
45        opts.limit = self.limit;
46        opts.batch_size = self
47            .limit
48            .filter(|&n| n > 0)
49            .map(|n| u32::try_from(n).unwrap_or(u32::MAX));
50        opts.skip = self.skip.map(|s| s as u64);
51        opts
52    }
53}