rusdb_core/
collection.rs

1use bson::{doc, Document};
2use serde::{de::DeserializeOwned, Serialize};
3use std::marker::PhantomData;
4use tonic::Status;
5use uuid::Uuid;
6
7use crate::RusDbConnection;
8
9#[derive(Clone)]
10pub struct RusDocument<T>
11where
12    T: Serialize + DeserializeOwned + Clone + std::fmt::Debug,
13{
14    _id: Uuid,
15    collection: RusCollection<T>,
16    pub document: T,
17}
18
19impl<T> std::fmt::Debug for RusDocument<T>
20where
21    T: Serialize + DeserializeOwned + Clone + std::fmt::Debug,
22{
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        write!(f, "{:?}", self.document)
25    }
26}
27
28impl<T> RusDocument<T>
29where
30    T: Serialize + DeserializeOwned + Clone + std::fmt::Debug,
31{
32    pub fn create(_id: Uuid, collection: RusCollection<T>, document: T) -> Self {
33        Self {
34            _id,
35            collection,
36            document,
37        }
38    }
39    pub fn from_slice(slice: &[u8], collection: RusCollection<T>) -> Result<Self, bson::de::Error> {
40        let doc = bson::from_slice::<Document>(slice)?;
41        Self::from_document(doc, collection)
42    }
43    pub fn from_document(
44        doc: Document,
45        collection: RusCollection<T>,
46    ) -> Result<Self, bson::de::Error> {
47        let _id: Uuid = bson::from_bson(doc.get("_id").expect("no id").clone())?;
48        let document: T = bson::from_document(doc)?;
49        Ok(Self {
50            _id,
51            document,
52            collection,
53        })
54    }
55    pub fn id(&self) -> Uuid {
56        self._id.clone()
57    }
58    pub fn to_document(&self) -> Result<Document, bson::ser::Error> {
59        let mut doc = bson::to_document(&self.document)?;
60        doc.insert("_id", bson::to_bson(&self._id)?);
61        Ok(doc)
62    }
63    fn id_doc(&self) -> Result<Document, bson::ser::Error> {
64        Ok(doc!("_id": bson::to_bson(&self._id)?))
65    }
66    pub fn to_vec(&self) -> Result<Vec<u8>, bson::ser::Error> {
67        bson::to_vec(&self.to_document()?)
68    }
69    pub async fn sync(&mut self) -> Result<(), Status> {
70        let doc = self.to_document().unwrap();
71        self.collection
72            .update(self.id_doc().unwrap(), doc, Some(1))
73            .await?;
74        Ok(())
75    }
76    pub async fn delete(mut self) -> Result<(), Status> {
77        if self
78            .collection
79            .remove(self.id_doc().unwrap(), Some(1))
80            .await?
81            == 1
82        {
83            drop(self);
84            Ok(())
85        } else {
86            Err(Status::aborted("no document was removed."))
87        }
88    }
89}
90
91#[derive(Clone)]
92pub struct RusCollection<T>
93where
94    T: Serialize + DeserializeOwned + Clone + std::fmt::Debug,
95{
96    collection: String,
97    conn: RusDbConnection,
98    document_type: PhantomData<T>,
99}
100
101impl<T> RusCollection<T>
102where
103    T: Serialize + DeserializeOwned + Clone + std::fmt::Debug,
104{
105    pub fn create(collection: String, conn: RusDbConnection) -> Self {
106        Self {
107            collection,
108            conn,
109            document_type: PhantomData::default(),
110        }
111    }
112    fn create_document_vec(&self, data: &[u8]) -> Result<RusDocument<T>, bson::de::Error> {
113        RusDocument::from_slice(data, self.clone())
114    }
115    pub async fn insert(&mut self, doc: T) -> Result<RusDocument<T>, Status> {
116        let res = self
117            .conn
118            .insert(&self.collection, bson::to_document(&doc).unwrap(), true)
119            .await?;
120        let res = res.get_ref();
121        if res.count == 0 {
122            Err(Status::aborted("no documents inserted."))
123        } else {
124            let docs: Vec<RusDocument<T>> = res
125                .inserts
126                .iter()
127                .map(|v| {
128                    let data = v.document.as_ref().expect("document data missing");
129                    self.create_document_vec(data).unwrap()
130                })
131                .collect();
132            for d in docs {
133                return Ok(d);
134            }
135            Err(Status::aborted("no document returned"))
136        }
137    }
138    pub async fn insert_many(&mut self, docs: Vec<T>) -> Result<Vec<RusDocument<T>>, Status> {
139        let res = self
140            .conn
141            .insert_many(
142                &self.collection,
143                docs.into_iter()
144                    .map(|v| bson::to_document(&v).unwrap())
145                    .collect(),
146                true,
147            )
148            .await?;
149        let res = res.get_ref();
150        if res.count == 0 {
151            Err(Status::aborted("no documents inserted."))
152        } else {
153            Ok(res
154                .inserts
155                .iter()
156                .map(|v| {
157                    let data = v.document.as_ref().expect("document data missing");
158                    self.create_document_vec(data).unwrap()
159                })
160                .collect())
161        }
162    }
163    pub async fn update(
164        &mut self,
165        filter: Document,
166        updates: Document,
167        limit: Option<u32>,
168    ) -> Result<Vec<RusDocument<T>>, Status> {
169        let res = self
170            .conn
171            .update(&self.collection, filter, updates, limit)
172            .await?;
173        let res = res.get_ref();
174        Ok(res
175            .updated
176            .iter()
177            .map(|v| self.create_document_vec(v).unwrap())
178            .collect())
179    }
180    pub async fn remove(&mut self, filter: Document, limit: Option<u32>) -> Result<u32, Status> {
181        let res = self.conn.remove(&self.collection, filter, limit).await?;
182        let res = res.get_ref();
183        Ok(res.count)
184    }
185    pub async fn find(
186        &mut self,
187        filter: Document,
188        limit: Option<u32>,
189    ) -> Result<Vec<RusDocument<T>>, Status> {
190        let res = self
191            .conn
192            .find(&self.collection, Some(filter), limit)
193            .await?;
194        let res = res.get_ref();
195        Ok(res
196            .documents
197            .iter()
198            .map(|v| self.create_document_vec(v).unwrap())
199            .collect())
200    }
201    pub async fn find_all(&mut self, limit: Option<u32>) -> Result<Vec<RusDocument<T>>, Status> {
202        let res = self.conn.find(&self.collection, None, limit).await?;
203        let res = res.get_ref();
204        Ok(res
205            .documents
206            .iter()
207            .map(|v| self.create_document_vec(v).unwrap())
208            .collect())
209    }
210    pub async fn get(&mut self, id: Uuid) -> Result<Option<RusDocument<T>>, Status> {
211        let id = id.to_string();
212        let res = self.conn.get(&self.collection, &id).await?;
213        let res = res.get_ref();
214        if let Some(doc) = &res.document {
215            Ok(Some(self.create_document_vec(doc).unwrap()))
216        } else {
217            Ok(None)
218        }
219    }
220    pub async fn truncate(&mut self) -> Result<u32, Status> {
221        let res = self.conn.remove(&self.collection, doc!(), None).await?;
222        let res = res.get_ref();
223        Ok(res.count)
224    }
225}