use actix::Addr; use actix_web::Message; use sqlx_core::postgres::PgPool; use crate::database::{Database, SharedDatabase, self}; use crate::model::{AccountOrder, OrderStatus, ShoppingCartId}; #[macro_export] macro_rules! order_async_handler { ($msg: ty, $async: ident, $res: ty) => { impl actix::Handler<$msg> for OrderManager { type Result = actix::ResponseActFuture>; fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result { use actix::WrapFuture; let db = self.db.clone(); Box::pin(async { $async(msg, db).await }.into_actor(self)) } } }; } #[derive(Debug, thiserror::Error)] pub enum Error {} pub type Result = std::result::Result; pub struct OrderManager { db: SharedDatabase, } impl actix::Actor for OrderManager { type Context = actix::Context; } impl OrderManager { pub fn new(db: SharedDatabase) -> Self { Self { db } } } #[derive(Message, Debug)] #[rtype(result = "Result")] pub struct CreateOrder { pub shopping_cart_id: ShoppingCartId, } pub(crate) async fn create_order(msg: CreateOrder, db: SharedDatabase) -> Result { let cart = match db.send(database) } pub fn change(current: OrderStatus, next: OrderStatus) -> Option { match (current, next) { // paying (OrderStatus::Confirmed, OrderStatus::Payed) => Some(OrderStatus::Payed), // delivering (OrderStatus::Confirmed | OrderStatus::Payed, OrderStatus::Delivered) => { Some(OrderStatus::Delivered) } // cancelling (OrderStatus::Confirmed, OrderStatus::Cancelled) => Some(OrderStatus::Cancelled), (OrderStatus::Payed, OrderStatus::Cancelled) => Some(OrderStatus::RequireRefund), (OrderStatus::Payed, OrderStatus::RequireRefund) => Some(OrderStatus::RequireRefund), (OrderStatus::RequireRefund, OrderStatus::Refunded) => Some(OrderStatus::Refunded), _ => None, } }