Organize code
This commit is contained in:
parent
b5dfb64f89
commit
e7446e7df2
1353
Cargo.lock
generated
1353
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,60 +4,61 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix = { version = "0.13.0" }
|
||||
actix-rt = { version = "2.7.0" }
|
||||
actix-web = { version = "4.0.1" }
|
||||
actix-web-httpauth = { version = "0.6.0" }
|
||||
actix-auth = { version = "0.1.0" }
|
||||
actix-cors = { version = "0.6.1" }
|
||||
actix-files = { version = "0.6.0" }
|
||||
actix-multipart = { version = "0.4.0" }
|
||||
actix-broker = { version = "0.4.2" }
|
||||
actix-identity = { version = "0.4.0" }
|
||||
actix-web-opentelemetry = { version = "0.12.0" }
|
||||
actix = { version = "0.13.0", features = [] }
|
||||
actix-rt = { version = "2.7.0", features = [] }
|
||||
actix-web = { version = "4.0.1", features = [] }
|
||||
actix-web-httpauth = { version = "0.6.0", features = [] }
|
||||
actix-cors = { version = "0.6.1", features = [] }
|
||||
actix-files = { version = "0.6.0", features = [] }
|
||||
actix-multipart = { version = "0.4.0", features = [] }
|
||||
actix-broker = { version = "0.4.2", features = [] }
|
||||
actix-identity = { version = "0.4.0", features = [] }
|
||||
actix-web-opentelemetry = { version = "0.12.0", features = [] }
|
||||
actix-session = { version = "0.6.2", features = ["actix-redis", "redis-actor-session"] }
|
||||
actix-redis = { version = "0.11.0" }
|
||||
actix-redis = { version = "0.11.0", features = [] }
|
||||
|
||||
gumdrop = { version = "0.8.1" }
|
||||
gumdrop = { version = "0.8.1", features = [] }
|
||||
|
||||
tera = { version = "1.15.0" }
|
||||
tera = { version = "1.15.0", features = [] }
|
||||
|
||||
tracing = { version = "0.1.33" }
|
||||
tracing = { version = "0.1.33", features = [] }
|
||||
|
||||
uuid = { version = "0.8.2", features = ["serde"] }
|
||||
chrono = { version = "*", features = ["serde"] }
|
||||
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
serde_json = { version = "1.0.79" }
|
||||
toml = { version = "0.5.8" }
|
||||
serde_json = { version = "1.0.79", features = [] }
|
||||
toml = { version = "0.5.8", features = [] }
|
||||
|
||||
sqlx = { version = "0.5.13", features = ["migrate", "runtime-actix-rustls", "all-types", "postgres"] }
|
||||
sqlx-core = { version = "0.5.13" }
|
||||
sqlx-core = { version = "0.5.13", features = [] }
|
||||
|
||||
thiserror = { version = "1.0.30" }
|
||||
thiserror = { version = "1.0.30", features = [] }
|
||||
|
||||
validator = { version = "0.14.0" }
|
||||
validator = { version = "0.14.0", features = [] }
|
||||
|
||||
log = { version = "0.4.16" }
|
||||
pretty_env_logger = { version = "0.4.0" }
|
||||
log = { version = "0.4.16", features = [] }
|
||||
pretty_env_logger = { version = "0.4.0", features = [] }
|
||||
|
||||
dotenv = { version = "0.15.0" }
|
||||
dotenv = { version = "0.15.0", features = [] }
|
||||
|
||||
derive_more = { version = "0.99.17" }
|
||||
parking_lot = { version = "0.12.0" }
|
||||
derive_more = { version = "0.99.17", features = [] }
|
||||
parking_lot = { version = "0.12.0", features = [] }
|
||||
|
||||
password-hash = { version = "0.4.0", features = ["alloc"] }
|
||||
argon2 = { version = "0.4.0", features = ["parallel", "password-hash"] }
|
||||
rand_core = { version = "0.6", features = ["std"] }
|
||||
|
||||
tokio = { version = "1.17.0", features = ["full"] }
|
||||
futures = { version = "0.3.21" }
|
||||
futures-util = { version = "0.3.21" }
|
||||
futures = { version = "0.3.21", features = [] }
|
||||
futures-util = { version = "0.3.21", features = [] }
|
||||
|
||||
jwt = { version = "0.16.0", features = [] }
|
||||
hmac = { version = "0.12.1" }
|
||||
sha2 = { version = "0.10.2" }
|
||||
hmac = { version = "0.12.1", features = [] }
|
||||
sha2 = { version = "0.10.2", features = [] }
|
||||
|
||||
oauth2 = { version = "4.1.0" }
|
||||
oauth2 = { version = "4.1.0", features = [] }
|
||||
|
||||
async-trait = { version = "0.1.53" }
|
||||
async-trait = { version = "0.1.53", features = [] }
|
||||
|
||||
jemallocator = { version = "0.3.2", features = [] }
|
||||
|
@ -1,11 +1,25 @@
|
||||
use actix::{Actor, Addr, Context, Message};
|
||||
|
||||
use crate::database::Database;
|
||||
use crate::database::{self, Database};
|
||||
use crate::model::{
|
||||
AccountId, ProductId, Quantity, QuantityUnit, ShoppingCartId, ShoppingCartItem,
|
||||
ShoppingCartItemId, ShoppingCartState,
|
||||
};
|
||||
use crate::{cart_async_handler, database};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! cart_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for CartManager {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
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 {
|
||||
|
@ -18,6 +18,21 @@ pub mod shopping_carts;
|
||||
pub mod stocks;
|
||||
pub mod tokens;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! db_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for Database {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||
use actix::WrapFuture;
|
||||
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:?}")]
|
||||
@ -46,6 +61,8 @@ pub struct Database {
|
||||
pool: PgPool,
|
||||
}
|
||||
|
||||
pub type SharedDatabase = actix::Addr<Database>;
|
||||
|
||||
impl Clone for Database {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod cart_manager;
|
||||
pub mod database;
|
||||
pub mod order_manager;
|
||||
pub mod token_manager;
|
||||
|
70
api/src/actors/order_manager.rs
Normal file
70
api/src/actors/order_manager.rs
Normal file
@ -0,0 +1,70 @@
|
||||
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<Self, Result<$res>>;
|
||||
|
||||
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<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub struct OrderManager {
|
||||
db: SharedDatabase,
|
||||
}
|
||||
|
||||
impl actix::Actor for OrderManager {
|
||||
type Context = actix::Context<Self>;
|
||||
}
|
||||
|
||||
impl OrderManager {
|
||||
pub fn new(db: SharedDatabase) -> Self {
|
||||
Self { db }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Message, Debug)]
|
||||
#[rtype(result = "Result<AccountOrder>")]
|
||||
pub struct CreateOrder {
|
||||
pub shopping_cart_id: ShoppingCartId,
|
||||
}
|
||||
|
||||
pub(crate) async fn create_order(msg: CreateOrder, db: SharedDatabase) -> Result<AccountOrder> {
|
||||
let cart = match db.send(database)
|
||||
}
|
||||
|
||||
pub fn change(current: OrderStatus, next: OrderStatus) -> Option<OrderStatus> {
|
||||
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,
|
||||
}
|
||||
}
|
@ -10,7 +10,23 @@ use sha2::Sha256;
|
||||
|
||||
use crate::database::{Database, TokenByJti};
|
||||
use crate::model::{AccountId, Audience, Token, TokenString};
|
||||
use crate::{database, token_async_handler, Role};
|
||||
use crate::{database, Role};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! token_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for TokenManager {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||
use actix::WrapFuture;
|
||||
let db = self.db.clone();
|
||||
let secret = self.secret.clone();
|
||||
Box::pin(async { $async(msg, db, secret).await }.into_actor(self))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*struct Jwt {
|
||||
/// cti (customer id): Customer uuid identifier used by payment service
|
||||
|
@ -1,21 +1 @@
|
||||
use crate::model::OrderStatus;
|
||||
|
||||
pub fn change(current: OrderStatus, next: OrderStatus) -> Option<OrderStatus> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use actix_web::middleware::Logger;
|
||||
use actix_web::web::Data;
|
||||
use actix_web::{App, HttpServer};
|
||||
use gumdrop::Options;
|
||||
use jemallocator::Jemalloc;
|
||||
use password_hash::SaltString;
|
||||
use validator::{validate_email, validate_length};
|
||||
|
||||
@ -20,7 +21,9 @@ pub mod actors;
|
||||
pub mod logic;
|
||||
pub mod model;
|
||||
pub mod routes;
|
||||
mod utils;
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: Jemalloc = Jemalloc;
|
||||
|
||||
trait ResolveDbUrl {
|
||||
fn own_db_url(&self) -> Option<String>;
|
||||
|
@ -178,7 +178,7 @@ async fn register(
|
||||
async fn landing() -> Result<HttpResponse> {
|
||||
Ok(HttpResponse::NotImplemented()
|
||||
.append_header(("Content-Type", "text/html"))
|
||||
.body(include_str!("../../../assets/index.html")))
|
||||
.body(include_str!("../../assets/index.html")))
|
||||
}
|
||||
|
||||
pub fn configure(config: &mut ServiceConfig) {
|
@ -20,7 +20,7 @@ pub enum Error {
|
||||
AddItem,
|
||||
}
|
||||
|
||||
pub fn configure(config: &mut ServiceConfig) {
|
||||
pub(crate) fn configure(config: &mut ServiceConfig) {
|
||||
config.service(
|
||||
scope("/api/v1")
|
||||
.configure(unrestricted::configure)
|
||||
|
@ -186,7 +186,9 @@ async fn delete_cart_item(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn configure(config: &mut ServiceConfig) {
|
||||
pub(crate) async fn create_order() {}
|
||||
|
||||
pub(crate) fn configure(config: &mut ServiceConfig) {
|
||||
config.service(scope("")
|
||||
.app_data(actix_web_httpauth::extractors::bearer::Config::default()
|
||||
.realm("user api")
|
||||
|
@ -84,6 +84,6 @@ async fn sign_in(
|
||||
Ok(HttpResponse::Created().json(SignInOutput { token: string }))
|
||||
}
|
||||
|
||||
pub fn configure(config: &mut ServiceConfig) {
|
||||
pub(crate) fn configure(config: &mut ServiceConfig) {
|
||||
config.service(products).service(stocks).service(sign_in);
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
#[macro_export]
|
||||
macro_rules! db_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for Database {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||
use actix::WrapFuture;
|
||||
let pool = self.pool.clone();
|
||||
Box::pin(async { $async(msg, pool).await }.into_actor(self))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! cart_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for CartManager {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! token_async_handler {
|
||||
($msg: ty, $async: ident, $res: ty) => {
|
||||
impl actix::Handler<$msg> for TokenManager {
|
||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||
|
||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||
use actix::WrapFuture;
|
||||
let db = self.db.clone();
|
||||
let secret = self.secret.clone();
|
||||
Box::pin(async { $async(msg, db, secret).await }.into_actor(self))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user