use bson::{Bson, Document};
use mongodb::{
coll::{results::InsertOneResult, Collection},
db::{Database, ThreadedDatabase},
};
use serde::{de::DeserializeOwned, Serialize};
use crate::error::Result;
pub trait DatabaseDocument: Serialize + DeserializeOwned {
const COLLECTION_NAME: &'static str;
type QueryData;
fn get_coll(db: &Database) -> Collection {
db.collection(Self::COLLECTION_NAME)
}
fn to_bson(&self) -> Document {
match bson::to_bson(self).unwrap() {
Bson::Document(doc) => doc,
_ => unreachable!("Did not serialize to Document!"),
}
}
fn from_bson(doc: Document) -> Result<Self> {
Ok(bson::from_bson(doc.into())?)
}
fn gen_query(query_data: &Self::QueryData) -> Document;
fn find(
db: &Database,
query_data: &Self::QueryData,
) -> Result<Option<Self>> {
let doc_opt = Self::get_coll(db)
.find_one(Some(Self::gen_query(query_data)), None)?;
Ok(match doc_opt {
Some(doc) => Some(Self::from_bson(doc)?),
None => None,
})
}
fn insert(&self, db: &Database) -> Result<InsertOneResult> {
Ok(Self::get_coll(db).insert_one(self.to_bson(), None)?)
}
}