Skip to content

Commit

Permalink
create order with json payload
Browse files Browse the repository at this point in the history
  • Loading branch information
Vovke committed Sep 20, 2024
1 parent dcda842 commit 1c72c05
Showing 1 changed file with 48 additions and 82 deletions.
130 changes: 48 additions & 82 deletions src/handlers/order.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,49 @@
use crate::{state::State, definitions::api_v2::OrderResponse};
use axum::{extract::{MatchedPath, RawPathParams, Query, State as ExtractState}, response::{IntoResponse, Response}, http::StatusCode, Json, extract};
use std::collections::HashMap;
use axum::extract::rejection::RawPathParamsRejection;
use axum_macros::debug_handler;
use crate::error::{OrderError, ForceWithdrawalError};
use crate::definitions::api_v2::{InvalidParameter, AMOUNT, CURRENCY, CALLBACK, OrderQuery, OrderStatus};
use axum::{
extract::{MatchedPath, Path, State as ExtractState},
response::{IntoResponse, Response},
Json,
http::StatusCode,
};
use crate::{
state::State,
definitions::api_v2::{OrderQuery, OrderResponse, InvalidParameter, AMOUNT, CURRENCY, CALLBACK, OrderStatus},
error::{OrderError, ForceWithdrawalError},
};
use serde::Deserialize;

async fn process_order(
#[derive(Debug, Deserialize)]
pub struct OrderPayload {
pub amount: f64,
pub currency: String,
pub callback: Option<String>,
}

pub async fn process_order(
state: State,
matched_path: &MatchedPath,
path_result: Result<RawPathParams, RawPathParamsRejection>,
query: &HashMap<String, String>,
order_id: String,
payload: OrderPayload,
) -> Result<OrderResponse, OrderError> {
const ORDER_ID: &str = "order_id";

let path_parameters =
path_result.map_err(|_| OrderError::InvalidParameter(matched_path.as_str().to_owned()))?;
let order = path_parameters
.iter()
.find_map(|(key, value)| (key == ORDER_ID).then_some(value))
.ok_or_else(|| OrderError::MissingParameter(ORDER_ID.into()))?
.to_owned();

if query.is_empty() {
state
.order_status(&order)
.await
.map_err(|_| OrderError::InternalError)
} else {
let get_parameter = |parameter: &str| {
query
.get(parameter)
.ok_or_else(|| OrderError::MissingParameter(parameter.into()))
};

let currency = get_parameter(CURRENCY)?.to_owned();
let callback = get_parameter(CALLBACK)?.to_owned();
let amount = get_parameter(AMOUNT)?
.parse()
.map_err(|_| OrderError::InvalidParameter(AMOUNT.into()))?;

if amount < 0.07 {
return Err(OrderError::LessThanExistentialDeposit(0.07));
}

state
.create_order(OrderQuery {
order,
amount,
callback,
currency,
})
.await
.map_err(|_| OrderError::InternalError)
if payload.amount < 0.07 {
return Err(OrderError::LessThanExistentialDeposit(0.07));
}

state
.create_order(OrderQuery {
order: order_id,
amount: payload.amount,
callback: payload.callback.unwrap_or_default(),
currency: payload.currency,
})
.await
.map_err(|_| OrderError::InternalError)
}

#[debug_handler]
pub async fn order(
extract::State(state): extract::State<State>,
matched_path: MatchedPath,
path_result: Result<RawPathParams, RawPathParamsRejection>,
query: Query<HashMap<String, String>>,
ExtractState(state): ExtractState<State>,
Path(order_id): Path<String>,
Json(payload): Json<OrderPayload>,
) -> Response {
match process_order(state, &matched_path, path_result, &query).await {
match process_order(state, order_id, payload).await {
Ok(order) => match order {
OrderResponse::NewOrder(order_status) => (StatusCode::CREATED, Json(order_status)).into_response(),
OrderResponse::FoundOrder(order_status) => (StatusCode::OK, Json(order_status)).into_response(),
Expand Down Expand Up @@ -109,33 +89,21 @@ pub async fn order(
}
}

async fn process_force_withdrawal(
pub async fn process_force_withdrawal(
state: State,
matched_path: &MatchedPath,
path_result: Result<RawPathParams, RawPathParamsRejection>,
order_id: String,
) -> Result<OrderStatus, ForceWithdrawalError> {
const ORDER_ID: &str = "order_id";

let path_parameters = path_result
.map_err(|_| ForceWithdrawalError::InvalidParameter(matched_path.as_str().to_owned()))?;
let order = path_parameters
.iter()
.find_map(|(key, value)| (key == ORDER_ID).then_some(value))
.ok_or_else(|| ForceWithdrawalError::MissingParameter(ORDER_ID.into()))?
.to_owned();
state
.force_withdrawal(order)
.force_withdrawal(order_id)
.await
.map_err(|e| ForceWithdrawalError::WithdrawalError(e.into()))
}

#[debug_handler]
pub async fn force_withdrawal(
extract::State(state): extract::State<State>,
matched_path: MatchedPath,
path_result: Result<RawPathParams, RawPathParamsRejection>,
ExtractState(state): ExtractState<State>,
Path(order_id): Path<String>,
) -> Response {
match process_force_withdrawal(state, &matched_path, path_result).await {
match process_force_withdrawal(state, order_id).await {
Ok(a) => (StatusCode::CREATED, Json(a)).into_response(),
Err(ForceWithdrawalError::WithdrawalError(a)) => {
(StatusCode::BAD_REQUEST, Json(a)).into_response()
Expand All @@ -159,12 +127,10 @@ pub async fn force_withdrawal(
}
}

#[debug_handler]
pub async fn investigate(
extract::State(state): extract::State<State>,
matched_path: MatchedPath,
path_result: Result<RawPathParams, RawPathParamsRejection>,
query: Query<HashMap<String, String>>,
ExtractState(_state): ExtractState<State>,
Path(_order_id): Path<String>,
) -> Response {
todo!()
// Investigation logic will be implemented here as needed
StatusCode::NOT_IMPLEMENTED.into_response()
}

0 comments on commit 1c72c05

Please sign in to comment.