use async_trait::async_trait;
use rskit_errors::AppResult;
#[async_trait]
pub trait Repository<T, ID>: Send + Sync
where
T: Send + Sync,
ID: Send + Sync,
{
async fn find_by_id(&self, id: &ID) -> AppResult<Option<T>>;
async fn find_all(&self, opts: FindOpts) -> AppResult<Vec<T>>;
async fn find_first(&self, opts: FindOpts) -> AppResult<Option<T>>;
async fn count(&self, opts: FindOpts) -> AppResult<i64>;
async fn exists(&self, id: &ID) -> AppResult<bool>;
async fn create(&self, entity: &T) -> AppResult<T>;
async fn update(&self, entity: &T) -> AppResult<T>;
async fn delete(&self, id: &ID) -> AppResult<()>;
async fn upsert(&self, entity: &T) -> AppResult<T>;
}
#[derive(Debug, Default)]
pub struct FindOpts {
pub limit: Option<i64>,
pub offset: Option<i64>,
pub order_by: Vec<String>,
pub filters: Vec<(String, serde_json::Value)>,
}
impl FindOpts {
#[must_use]
pub fn with_limit(mut self, n: i64) -> Self {
self.limit = Some(n);
self
}
#[must_use]
pub fn with_offset(mut self, n: i64) -> Self {
self.offset = Some(n);
self
}
#[must_use]
pub fn order_by(mut self, col: &str) -> Self {
self.order_by.push(col.to_owned());
self
}
#[must_use]
pub fn filter(mut self, col: &str, val: impl Into<serde_json::Value>) -> Self {
self.filters.push((col.to_owned(), val.into()));
self
}
}