parker 0.0.0

Minimalist web framework for templatized rendering
Documentation
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 {
    /// The name of the Mongo collection to store this document type in.
    const COLLECTION_NAME: &'static str;
    /// The type of data that will be used to query for this document.
    type QueryData;

    /// Get the collection that this type belongs in, from the given database.
    fn get_coll(db: &Database) -> Collection {
        db.collection(Self::COLLECTION_NAME)
    }

    /// Converts this object to a BSON document.
    fn to_bson(&self) -> Document {
        // to_bson will always return Ok
        match bson::to_bson(self).unwrap() {
            Bson::Document(doc) => doc,
            _ => unreachable!("Did not serialize to Document!"),
        }
    }

    /// Convert the given BSON Document to this type.
    fn from_bson(doc: Document) -> Result<Self> {
        Ok(bson::from_bson(doc.into())?)
    }

    /// Generate a query document based on the given query data.
    fn gen_query(query_data: &Self::QueryData) -> Document;

    /// Find a document from this type's collection, based on the given query
    /// data.
    fn find(
        db: &Database,
        query_data: &Self::QueryData,
    ) -> Result<Option<Self>> {
        // Get the value from the DB
        let doc_opt = Self::get_coll(db)
            .find_one(Some(Self::gen_query(query_data)), None)?;
        // Parse to this type
        Ok(match doc_opt {
            Some(doc) => Some(Self::from_bson(doc)?),
            None => None,
        })
    }

    /// Insert this document into the database.
    fn insert(&self, db: &Database) -> Result<InsertOneResult> {
        Ok(Self::get_coll(db).insert_one(self.to_bson(), None)?)
    }
}