use anyhow::Result;
use mongodb::{
bson::{Document, to_document, from_document},
options::ClientOptions, Client, Collection, Cursor, Database
};
use serde::{de::DeserializeOwned, Serialize};
use std::marker::{Send, Sync, Unpin};
pub struct Records<T> {
db: Collection<T>,
}
impl<T> Records<T>
where
T: DeserializeOwned + Serialize + Unpin + Sync + Send,
{
pub fn new(name: &str, database: &Database) -> Records<T> {
Records {
db: database.collection::<T>(name),
}
}
pub async fn get_many(&self, filter: Document) -> Result<Vec<T>> {
let mut buffer: Vec<T> = Vec::new();
let mut cursor = self.db.find(filter, None).await?;
while cursor.advance().await? {
buffer.push(cursor.deserialize_current()?);
}
Ok(buffer)
}
pub async fn get_many_as_cursor(&self, filter: Document) -> Result<Cursor<T>> {
Ok(self.db.find(filter, None).await?)
}
pub async fn get(&self, filter: Document) -> Result<Option<T>> {
Ok(self.db.find_one(filter, None).await?)
}
pub async fn exists(&self, filter: Document) -> Result<bool> {
Ok(self.get(filter).await?.is_some())
}
pub async fn put(&self, document: &T) -> Result<()> {
self.db.insert_one(document, None).await?;
Ok(())
}
pub async fn delete_many(&self, filter: Document) -> Result<()> {
self.db.delete_many(filter, None).await?;
Ok(())
}
pub async fn delete(&self, filter: Document) -> Result<()> {
self.db.delete_one(filter, None).await?;
Ok(())
}
pub async fn update(&self, filter: Document, next: &T) -> Result<()> {
self.db.replace_one(filter, next, None).await?;
Ok(())
}
pub async fn count(&self) -> Result<u64> {
return Ok(self.db.estimated_document_count(None).await?);
}
}
pub trait AsDocument: Serialize {
fn as_doc(&self) -> Result<Document> {
Ok(to_document(self)?)
}
}
pub trait FromDocument: DeserializeOwned {
fn from_doc(document: Document) -> Result<Self> {
Ok(from_document(document)?)
}
}
pub async fn get_db(uri: &str, name: &str) -> Result<Database> {
Ok(Client::with_options(ClientOptions::parse(uri).await?)?.database(name))
}