mongor 0.1.10

Ergonomic MongoDB ODM
Documentation
// Authors: Robert Lopez
// License: MIT (See `LICENSE.md`)

use super::Model;
use crate::{
    core::{delete::*, find::*, replace::*, update::*},
    error::Error,
};
use mongodb::{
    bson::{doc, Document},
    options::*,
    results::{DeleteResult, UpdateResult},
    ClientSession,
};
use serde::{Deserialize, Serialize};

impl<D> Model<D>
where
    D: Serialize + for<'a> Deserialize<'a> + Send + Sync + Unpin,
{
    /// Executes a `findOne` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.findOne/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let document_option: Option<D> = model.find_one_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     None::<FindOneOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn find_one_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        options: Option<FindOneOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<Option<D>, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        find_one(&self.collection, doc! { field: value }, options, session).await
    }

    /// Executes a `find` query on `self.collection` by document `field` and
    /// its corresponding `value`, returning a cursor to iterate over.
    ///
    /// See: `core::find::FindManyCursor`
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.find/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let mut cursor: FindManyCursor<D> = model.find_many_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     None::<FindOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    ///
    /// while let Some(document: D) = cursor.next_with_session(&mut session).await? {
    ///     ...
    /// }
    /// ```
    pub async fn find_many_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        options: Option<FindOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<FindManyCursor<D>, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        FindManyCursor::from(&self.collection, doc! { field: value}, options, session).await
    }

    /// Executes a `deleteOne` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteOne/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let deletion_result: DeleteResult = model.delete_one_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     None::<DeleteOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn delete_one_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        options: Option<DeleteOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<DeleteResult, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        delete_one(&self.collection, doc! { field: value }, options, session).await
    }

    /// Executes a `deleteMany` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteMany/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let deletion_result: DeleteResult = model.delete_many_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     None::<DeleteOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn delete_many_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        options: Option<DeleteOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<DeleteResult, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        delete_many(&self.collection, doc! { field: value }, options, session).await
    }

    /// Executes a `updateOne` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let update_result: UpdateResult = model.update_one_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     doc! { ... },
    ///     None::<UpdateOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn update_one_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        update: Document,
        options: Option<UpdateOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<UpdateResult, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        update_one(
            &self.collection,
            doc! { field: value },
            update,
            options,
            session,
        )
        .await
    }

    /// Executes a `updateMany` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.updateMany/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let update_result: UpdateResult = model.update_many_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     doc! { ... },
    ///     None::<UpdateOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn update_many_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        update: Document,
        options: Option<UpdateOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<UpdateResult, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        update_many(
            &self.collection,
            doc! { field: value },
            update,
            options,
            session,
        )
        .await
    }

    /// Executes a `findOneAndUpdate` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.findOneAndUpdate/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let updated_document: Option<D> = model.find_one_and_update_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     doc! { ... },
    ///     None::<FindOneAndUpdateOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn find_one_and_update_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        update: Document,
        options: Option<FindOneAndUpdateOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<Option<D>, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        find_one_and_update(
            &self.collection,
            doc! { field: value },
            update,
            options,
            session,
        )
        .await
    }

    /// Executes a `findOneAndReplace` query on `self.collection` by a document `field` and
    /// its corresponding `value`.
    ///
    /// https://www.mongodb.com/docs/manual/reference/method/db.collection.findOneAndReplace/
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let mut model: Model<D> = ...;
    ///
    /// let replacement: D = ...;
    ///
    /// let original_document: Option<D> = model.find_one_and_replace_by_field_value(
    ///     "some_field",
    ///     1337,
    ///     replacement,
    ///     None::<FindOneAndReplaceOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await?;
    /// ```
    pub async fn find_one_and_replace_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        replacement: D,
        options: Option<FindOneAndReplaceOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<Option<D>, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        find_one_and_replace(
            &self.collection,
            doc! { field: value },
            replacement,
            options,
            session,
        )
        .await
    }

    /// Returns if a document exists by a field and value
    /// in `self.collection`.
    ///
    /// ---
    /// Example Usage:
    /// ```
    ///
    /// let model: Model<D> = ...;
    ///
    /// if model.exists_by_field_value(
    ///     "field",
    ///     1337,
    ///     None::<FindOneOptions>,
    ///     None::<&mut ClientSession>,
    /// ).await? {
    ///     ...
    /// }
    /// ```
    pub async fn exists_by_field_value<F, V>(
        &self,
        field: F,
        value: V,
        options: Option<FindOneOptions>,
        session: Option<&mut ClientSession>,
    ) -> Result<bool, Error>
    where
        F: Into<std::string::String>,
        std::string::String: From<F>,
        V: Into<mongodb::bson::Bson>,
        mongodb::bson::Bson: From<V>,
    {
        Ok(self
            .find_one_by_field_value(field, value, options, session)
            .await?
            .is_some())
    }
}