use crate::error::oximod_error::OxiModError;
use crate::feature::conn::client::OxiClient;
use async_trait;
use mongodb::Client;
use mongodb::{
Collection,
bson::{Document, doc, oid::ObjectId},
results::{DeleteResult, UpdateResult},
};
use serde::de::DeserializeOwned;
#[async_trait::async_trait]
pub trait Model
where
Self: DeserializeOwned + Send + Sync + Sized,
{
fn get_collection_from(client: &mongodb::Client) -> Result<Collection<Self>, OxiModError>;
fn get_document_collection_from(
client: &mongodb::Client,
) -> Result<Collection<Document>, OxiModError> {
Ok(Self::get_collection_from(client)?.clone_with_type::<Document>())
}
async fn save_from(&self, client: &mongodb::Client) -> Result<ObjectId, OxiModError>;
async fn save_from_mut(&mut self, client: &mongodb::Client) -> Result<ObjectId, OxiModError>;
async fn clear_from(client: &mongodb::Client) -> Result<DeleteResult, OxiModError>;
async fn find_by_id_from(
id: ObjectId,
client: &mongodb::Client,
) -> Result<Option<Self>, OxiModError>;
async fn delete_by_id_from(
id: ObjectId,
client: &mongodb::Client,
) -> Result<DeleteResult, OxiModError>;
async fn update_by_id_from(
id: ObjectId,
update: Document,
client: &mongodb::Client,
) -> Result<UpdateResult, OxiModError>;
async fn exists_from(filter: Document, client: &mongodb::Client) -> Result<bool, OxiModError> {
let collection = Self::get_collection_from(client)?;
let found = collection
.find_one(filter)
.await
.map_err(|e| OxiModError::database("Failed to check document existence", e))?;
Ok(found.is_some())
}
async fn count_from(filter: Document, client: &mongodb::Client) -> Result<u64, OxiModError> {
let collection = Self::get_collection_from(client)?;
collection
.count_documents(filter)
.await
.map_err(|e| OxiModError::database("Failed to count matching documents", e))
}
fn get_collection() -> Result<Collection<Self>, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::get_collection_from(client)
}
fn get_document_collection() -> Result<Collection<Document>, OxiModError> {
Ok(Self::get_collection()?.clone_with_type::<Document>())
}
async fn save(&self) -> Result<ObjectId, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
self.save_from(client).await
}
async fn save_mut(&mut self) -> Result<ObjectId, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
self.save_from_mut(client).await
}
async fn clear() -> Result<DeleteResult, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::clear_from(client).await
}
async fn find_by_id(id: ObjectId) -> Result<Option<Self>, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::find_by_id_from(id, client).await
}
async fn delete_by_id(id: ObjectId) -> Result<DeleteResult, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::delete_by_id_from(id, client).await
}
async fn update_by_id(id: ObjectId, update: Document) -> Result<UpdateResult, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::update_by_id_from(id, update, client).await
}
async fn exists(filter: Document) -> Result<bool, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::exists_from(filter, client).await
}
async fn count(filter: Document) -> Result<u64, OxiModError> {
let client_arc = OxiClient::global()?;
let client: &Client = client_arc.as_ref();
Self::count_from(filter, client).await
}
fn validate(&self) -> Result<(), OxiModError>;
}