60 lines
1.4 KiB
Rust
60 lines
1.4 KiB
Rust
use diesel::{pg::PgConnection, result::Error as DieselError};
|
|
use uuid::Uuid;
|
|
|
|
use crate::{
|
|
error::{AppError, AppResult},
|
|
state::AppState,
|
|
};
|
|
|
|
pub trait EnsureEntity<T> {
|
|
fn one(self) -> AppResult<T>;
|
|
fn maybe(self) -> AppResult<Option<T>>;
|
|
}
|
|
|
|
impl<T> EnsureEntity<T> for Result<T, DieselError> {
|
|
fn one(self) -> AppResult<T> {
|
|
self.map_err(AppError::from)
|
|
}
|
|
|
|
fn maybe(self) -> AppResult<Option<T>> {
|
|
match self {
|
|
Ok(value) => Ok(Some(value)),
|
|
Err(DieselError::NotFound) => Ok(None),
|
|
Err(err) => Err(AppError::from(err)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AppState {
|
|
pub fn with_tenant_conn<F, T>(&self, tenant_id: Uuid, f: F) -> AppResult<T>
|
|
where
|
|
F: FnOnce(&mut PgConnection) -> AppResult<T>,
|
|
{
|
|
let mut conn = self.db_for_tenant(tenant_id)?;
|
|
f(&mut conn)
|
|
}
|
|
}
|
|
|
|
pub fn validate_bulk_ids(ids: &mut Vec<Uuid>, label: &str) -> AppResult<()> {
|
|
if ids.is_empty() {
|
|
return Err(AppError::bad_request(format!("{label} must not be empty")));
|
|
}
|
|
ids.sort_unstable();
|
|
ids.dedup();
|
|
Ok(())
|
|
}
|
|
|
|
pub trait IntoJsonResponse<T> {
|
|
fn into_json(self) -> AppResult<axum::Json<T>>;
|
|
}
|
|
|
|
impl<T> IntoJsonResponse<T> for T {
|
|
fn into_json(self) -> AppResult<axum::Json<T>> {
|
|
Ok(axum::Json(self))
|
|
}
|
|
}
|
|
|
|
pub fn no_content() -> AppResult<axum::http::StatusCode> {
|
|
Ok(axum::http::StatusCode::NO_CONTENT)
|
|
}
|