use diesel::{pg::PgConnection, result::Error as DieselError}; use uuid::Uuid; use crate::{ error::{AppError, AppResult}, state::AppState, }; pub trait EnsureEntity { fn one(self) -> AppResult; fn maybe(self) -> AppResult>; } impl EnsureEntity for Result { fn one(self) -> AppResult { self.map_err(AppError::from) } fn maybe(self) -> AppResult> { 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(&self, tenant_id: Uuid, f: F) -> AppResult where F: FnOnce(&mut PgConnection) -> AppResult, { let mut conn = self.db_for_tenant(tenant_id)?; f(&mut conn) } } pub fn validate_bulk_ids(ids: &mut Vec, 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 { fn into_json(self) -> AppResult>; } impl IntoJsonResponse for T { fn into_json(self) -> AppResult> { Ok(axum::Json(self)) } } pub fn no_content() -> AppResult { Ok(axum::http::StatusCode::NO_CONTENT) }