Add wrapper around repository backend error

This commit is contained in:
2025-01-29 20:24:41 +00:00
parent d2de03fde1
commit fc07051558
8 changed files with 58 additions and 35 deletions

View File

@@ -10,7 +10,7 @@ pub trait RepositoryProvider {
where where
Self: 'a; Self: 'a;
async fn get(&self) -> Result<Self::Repository<'_>, Self::BackendError>; async fn get(&self) -> Result<Self::Repository<'_>, RepositoryError<Self::BackendError>>;
} }
pub trait Repository pub trait Repository
@@ -19,3 +19,6 @@ where
{ {
type BackendError: std::error::Error; type BackendError: std::error::Error;
} }
#[derive(Debug)]
pub struct RepositoryError<E>(pub E);

View File

@@ -1,14 +1,16 @@
use super::RepositoryError;
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait UserRepository { pub trait UserRepository {
type BackendError: std::error::Error; type BackendError: std::error::Error;
async fn user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError>; async fn user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>>;
async fn insert_user(&mut self, new_user: NewUser) -> Result<User, Self::BackendError>; async fn insert_user(&mut self, new_user: NewUser) -> Result<User, RepositoryError<Self::BackendError>>;
async fn update_user(&mut self, user: User) -> Result<Option<User>, Self::BackendError>; async fn update_user(&mut self, user: User) -> Result<Option<User>, RepositoryError<Self::BackendError>>;
async fn remove_user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError>; async fn remove_user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>>;
} }
pub struct User { pub struct User {

View File

@@ -2,6 +2,7 @@ use diesel_async::pooled_connection::bb8::Pool;
use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::pooled_connection::bb8::PooledConnection;
use diesel_async::AsyncMysqlConnection; use diesel_async::AsyncMysqlConnection;
use rotom_core::repository::Repository; use rotom_core::repository::Repository;
use rotom_core::repository::RepositoryError;
use rotom_core::repository::RepositoryProvider; use rotom_core::repository::RepositoryProvider;
use crate::BackendError; use crate::BackendError;
@@ -38,7 +39,11 @@ impl RepositoryProvider for MysqlRepositoryProvider {
type Repository<'a> = MysqlRepository<'a>; type Repository<'a> = MysqlRepository<'a>;
async fn get(&self) -> Result<Self::Repository<'_>, Self::BackendError> { async fn get(&self) -> Result<Self::Repository<'_>, RepositoryError<Self::BackendError>> {
self.pool.get().await.map(MysqlRepository::new).map_err(BackendError::from) self.pool
.get()
.await
.map(MysqlRepository::new)
.map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }

View File

@@ -5,6 +5,7 @@ use diesel_async::RunQueryDsl;
use rotom_core::repository::user_repository::NewUser; use rotom_core::repository::user_repository::NewUser;
use rotom_core::repository::user_repository::User; use rotom_core::repository::user_repository::User;
use rotom_core::repository::user_repository::UserRepository; use rotom_core::repository::user_repository::UserRepository;
use rotom_core::repository::RepositoryError;
use crate::mysql::schema::users; use crate::mysql::schema::users;
use crate::BackendError; use crate::BackendError;
@@ -16,16 +17,16 @@ use super::MysqlRepository;
impl UserRepository for MysqlRepository<'_> { impl UserRepository for MysqlRepository<'_> {
type BackendError = BackendError; type BackendError = BackendError;
async fn user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
users::dsl::users.find(id) users::dsl::users.find(id)
.first::<ModelUser>(&mut self.conn) .first::<ModelUser>(&mut self.conn)
.await .await
.optional() .optional()
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn insert_user(&mut self, new_user: NewUser) -> Result<User, Self::BackendError> { async fn insert_user(&mut self, new_user: NewUser) -> Result<User, RepositoryError<Self::BackendError>> {
let model_new_user = ModelNewUser::from(new_user); let model_new_user = ModelNewUser::from(new_user);
self.conn self.conn
@@ -43,10 +44,10 @@ impl UserRepository for MysqlRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(User::from) .map(User::from)
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn update_user(&mut self, user: User) -> Result<Option<User>, Self::BackendError> { async fn update_user(&mut self, user: User) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
let model_user = ModelUser::from(user); let model_user = ModelUser::from(user);
self.conn self.conn
@@ -71,10 +72,10 @@ impl UserRepository for MysqlRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn remove_user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn remove_user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
self.conn self.conn
.transaction::<_, diesel::result::Error, _>(move |conn| async move { .transaction::<_, diesel::result::Error, _>(move |conn| async move {
let option_removed = users::dsl::users.find(id) let option_removed = users::dsl::users.find(id)
@@ -97,7 +98,7 @@ impl UserRepository for MysqlRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }

View File

@@ -2,6 +2,7 @@ use diesel_async::pooled_connection::bb8::Pool;
use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::pooled_connection::bb8::PooledConnection;
use diesel_async::AsyncPgConnection; use diesel_async::AsyncPgConnection;
use rotom_core::repository::Repository; use rotom_core::repository::Repository;
use rotom_core::repository::RepositoryError;
use rotom_core::repository::RepositoryProvider; use rotom_core::repository::RepositoryProvider;
use crate::BackendError; use crate::BackendError;
@@ -38,7 +39,11 @@ impl RepositoryProvider for PostgresRepositoryProvider {
type Repository<'a> = PostgresRepository<'a>; type Repository<'a> = PostgresRepository<'a>;
async fn get(&self) -> Result<Self::Repository<'_>, Self::BackendError> { async fn get(&self) -> Result<Self::Repository<'_>, RepositoryError<Self::BackendError>> {
self.pool.get().await.map(PostgresRepository::new).map_err(BackendError::from) self.pool
.get()
.await
.map(PostgresRepository::new)
.map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }

View File

@@ -5,6 +5,7 @@ use diesel_async::RunQueryDsl;
use rotom_core::repository::user_repository::NewUser; use rotom_core::repository::user_repository::NewUser;
use rotom_core::repository::user_repository::User; use rotom_core::repository::user_repository::User;
use rotom_core::repository::user_repository::UserRepository; use rotom_core::repository::user_repository::UserRepository;
use rotom_core::repository::RepositoryError;
use crate::postgres::schema::users; use crate::postgres::schema::users;
use crate::BackendError; use crate::BackendError;
@@ -16,16 +17,16 @@ use super::PostgresRepository;
impl UserRepository for PostgresRepository<'_> { impl UserRepository for PostgresRepository<'_> {
type BackendError = BackendError; type BackendError = BackendError;
async fn user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
users::dsl::users.find(id) users::dsl::users.find(id)
.first::<ModelUser>(&mut self.conn) .first::<ModelUser>(&mut self.conn)
.await .await
.optional() .optional()
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn insert_user(&mut self, new_user: NewUser) -> Result<User, Self::BackendError> { async fn insert_user(&mut self, new_user: NewUser) -> Result<User, RepositoryError<Self::BackendError>> {
let model_new_user = ModelNewUser::from(new_user); let model_new_user = ModelNewUser::from(new_user);
self.conn self.conn
@@ -38,10 +39,10 @@ impl UserRepository for PostgresRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(User::from) .map(User::from)
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn update_user(&mut self, user: User) -> Result<Option<User>, Self::BackendError> { async fn update_user(&mut self, user: User) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
let model_user = ModelUser::from(user); let model_user = ModelUser::from(user);
self.conn self.conn
@@ -66,10 +67,10 @@ impl UserRepository for PostgresRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn remove_user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn remove_user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
self.conn self.conn
.transaction::<_, diesel::result::Error, _>(move |conn| async move { .transaction::<_, diesel::result::Error, _>(move |conn| async move {
diesel::delete(users::dsl::users.find(id)) diesel::delete(users::dsl::users.find(id))
@@ -80,7 +81,7 @@ impl UserRepository for PostgresRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }

View File

@@ -3,6 +3,7 @@ use diesel_async::pooled_connection::bb8::Pool;
use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::pooled_connection::bb8::PooledConnection;
use diesel_async::sync_connection_wrapper::SyncConnectionWrapper; use diesel_async::sync_connection_wrapper::SyncConnectionWrapper;
use rotom_core::repository::Repository; use rotom_core::repository::Repository;
use rotom_core::repository::RepositoryError;
use rotom_core::repository::RepositoryProvider; use rotom_core::repository::RepositoryProvider;
use crate::BackendError; use crate::BackendError;
@@ -39,7 +40,11 @@ impl RepositoryProvider for SqliteRepositoryProvider {
type Repository<'a> = SqliteRepository<'a>; type Repository<'a> = SqliteRepository<'a>;
async fn get(&self) -> Result<Self::Repository<'_>, Self::BackendError> { async fn get(&self) -> Result<Self::Repository<'_>, RepositoryError<Self::BackendError>> {
self.pool.get().await.map(SqliteRepository::new).map_err(BackendError::from) self.pool
.get()
.await
.map(SqliteRepository::new)
.map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }

View File

@@ -5,6 +5,7 @@ use diesel_async::RunQueryDsl;
use rotom_core::repository::user_repository::NewUser; use rotom_core::repository::user_repository::NewUser;
use rotom_core::repository::user_repository::User; use rotom_core::repository::user_repository::User;
use rotom_core::repository::user_repository::UserRepository; use rotom_core::repository::user_repository::UserRepository;
use rotom_core::repository::RepositoryError;
use crate::sqlite::schema::users; use crate::sqlite::schema::users;
use crate::BackendError; use crate::BackendError;
@@ -16,16 +17,16 @@ use super::SqliteRepository;
impl UserRepository for SqliteRepository<'_> { impl UserRepository for SqliteRepository<'_> {
type BackendError = BackendError; type BackendError = BackendError;
async fn user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
users::dsl::users.find(id) users::dsl::users.find(id)
.first::<ModelUser>(&mut self.conn) .first::<ModelUser>(&mut self.conn)
.await .await
.optional() .optional()
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn insert_user(&mut self, new_user: NewUser) -> Result<User, Self::BackendError> { async fn insert_user(&mut self, new_user: NewUser) -> Result<User, RepositoryError<Self::BackendError>> {
let model_new_user = ModelNewUser::from(new_user); let model_new_user = ModelNewUser::from(new_user);
self.conn self.conn
@@ -38,10 +39,10 @@ impl UserRepository for SqliteRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(User::from) .map(User::from)
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn update_user(&mut self, user: User) -> Result<Option<User>, Self::BackendError> { async fn update_user(&mut self, user: User) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
let model_user = ModelUser::from(user); let model_user = ModelUser::from(user);
self.conn self.conn
@@ -66,10 +67,10 @@ impl UserRepository for SqliteRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
async fn remove_user(&mut self, id: i32) -> Result<Option<User>, Self::BackendError> { async fn remove_user(&mut self, id: i32) -> Result<Option<User>, RepositoryError<Self::BackendError>> {
self.conn self.conn
.transaction::<_, diesel::result::Error, _>(move |conn| async move { .transaction::<_, diesel::result::Error, _>(move |conn| async move {
diesel::delete(users::dsl::users.find(id)) diesel::delete(users::dsl::users.find(id))
@@ -80,7 +81,7 @@ impl UserRepository for SqliteRepository<'_> {
}.scope_boxed()) }.scope_boxed())
.await .await
.map(|option| option.map(User::from)) .map(|option| option.map(User::from))
.map_err(BackendError::from) .map_err(|err| RepositoryError(BackendError::from(err)))
} }
} }