use crate::error::Result;
use async_trait::async_trait;
use serde::{de::DeserializeOwned, Serialize};
#[async_trait]
pub trait MongoRepository<T>: Send + Sync
where
T: Send + Sync + Serialize + DeserializeOwned,
{
async fn find_by_id(&self, id: &str) -> Result<Option<T>>;
async fn find_all(&self) -> Result<Vec<T>>;
async fn find(&self, filter: serde_json::Value) -> Result<Vec<T>>;
async fn find_one(&self, filter: serde_json::Value) -> Result<Option<T>>;
async fn insert_one(&self, doc: &T) -> Result<String>;
async fn insert_many(&self, docs: &[T]) -> Result<Vec<String>>;
async fn update_one(&self, id: &str, update: serde_json::Value) -> Result<bool>;
async fn update_many(
&self,
filter: serde_json::Value,
update: serde_json::Value,
) -> Result<u64>;
async fn delete_one(&self, id: &str) -> Result<bool>;
async fn delete_many(&self, filter: serde_json::Value) -> Result<u64>;
async fn count(&self, filter: Option<serde_json::Value>) -> Result<u64>;
}
pub struct AggregationBuilder {
stages: Vec<serde_json::Value>,
}
impl AggregationBuilder {
pub fn new() -> Self {
Self { stages: Vec::new() }
}
pub fn match_stage(mut self, filter: serde_json::Value) -> Self {
self.stages.push(serde_json::json!({ "$match": filter }));
self
}
pub fn group(mut self, group: serde_json::Value) -> Self {
self.stages.push(serde_json::json!({ "$group": group }));
self
}
pub fn sort(mut self, sort: serde_json::Value) -> Self {
self.stages.push(serde_json::json!({ "$sort": sort }));
self
}
pub fn limit(mut self, n: i64) -> Self {
self.stages.push(serde_json::json!({ "$limit": n }));
self
}
pub fn skip(mut self, n: i64) -> Self {
self.stages.push(serde_json::json!({ "$skip": n }));
self
}
pub fn build(self) -> Vec<serde_json::Value> {
self.stages
}
}
impl Default for AggregationBuilder {
fn default() -> Self {
Self::new()
}
}