use actix::{Actor, Context}; use sqlx::PgPool; pub use account_orders::*; pub use accounts::*; pub use order_items::*; pub use products::*; pub use stocks::*; mod account_orders; mod accounts; mod order_items; mod products; mod stocks; #[macro_export] macro_rules! async_handler { ($msg: ty, $async: ident, $res: ty) => { impl Handler<$msg> for Database { type Result = ResponseActFuture>; fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result { let pool = self.pool.clone(); Box::pin(async { $async(msg, pool).await }.into_actor(self)) } } }; } #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Failed to connect to database. {0:?}")] Connect(sqlx::Error), #[error("{0}")] Account(accounts::Error), #[error("{0}")] AccountOrder(account_orders::Error), #[error("{0}")] Product(products::Error), #[error("{0}")] Stock(stocks::Error), #[error("{0}")] OrderItem(order_items::Error), } pub type Result = std::result::Result; pub struct Database { pool: PgPool, } impl Clone for Database { fn clone(&self) -> Self { Self { pool: self.pool.clone() } } } impl Database { pub(crate) async fn build(url: &str) -> Result { let pool = sqlx::PgPool::connect(url).await.map_err(Error::Connect)?; Ok(Database { pool }) } pub fn pool(&self) -> &PgPool { &self.pool } } impl Actor for Database { type Context = Context; }