revolt_database/util/
chunked.rs1#[cfg(feature = "mongodb")]
2use ::mongodb::{ClientSession, SessionCursor};
3use revolt_result::{Result, ToRevoltError};
4use serde::Deserialize;
5
6#[derive(Debug)]
7#[allow(clippy::large_enum_variant)]
8pub enum ChunkedDatabaseGenerator<T> {
9 #[cfg(feature = "mongodb")]
10 MongoDb {
11 session: ClientSession,
12 cursor: SessionCursor<T>,
13 },
14
15 Reference {
16 offset: usize,
17 data: Vec<T>,
18 },
19}
20
21impl<T: for<'d> Deserialize<'d> + Clone> ChunkedDatabaseGenerator<T> {
22 #[cfg(feature = "mongodb")]
23 pub fn new_mongo(session: ClientSession, cursor: SessionCursor<T>) -> Self {
24 Self::MongoDb { session, cursor }
25 }
26
27 pub fn new_reference(data: Vec<T>) -> Self {
28 Self::Reference { offset: 0, data }
29 }
30
31 pub async fn next(&mut self) -> Result<Option<T>> {
32 match self {
33 #[cfg(feature = "mongodb")]
34 Self::MongoDb { session, cursor } => {
35 cursor.next(session).await.transpose().to_internal_error()
36 }
37 Self::Reference { offset, data } => {
38 if let Some(value) = data.get(*offset) {
39 *offset += 1;
40 Ok(Some(value.clone()))
41 } else {
42 Ok(None)
43 }
44 }
45 }
46 }
47
48 pub async fn next_n(&mut self, n: usize) -> Result<Option<Vec<T>>> {
49 let mut docs = Vec::new();
50
51 while docs.len() < n {
52 if let Some(doc) = self.next().await? {
53 docs.push(doc);
54 } else if docs.is_empty() {
55 return Ok(None);
56 } else {
57 break;
58 }
59 }
60
61 Ok(Some(docs))
62 }
63}