use std::sync::Arc; use axum::{ Json, extract::{Path, State}, http::StatusCode, response::IntoResponse, }; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::routes::api::{ApiRouter, AppError}; use crate::service::proxy::rewrite_rule::{ CreateRewriteRuleParams, RewriteRuleService, UpdateRewriteRuleParams, }; use crate::service::proxy::types::RewriteRuleConfig; #[derive(Serialize)] pub(crate) struct RewriteRuleResponse { pub id: Uuid, pub location_id: Uuid, pub pattern: String, pub replacement: String, pub flag: Option, pub priority: i32, pub override_of_id: Option, } impl From for RewriteRuleResponse { fn from(c: RewriteRuleConfig) -> Self { Self { id: c.id, location_id: c.location_id, pattern: c.pattern, replacement: c.replacement, flag: c.flag, priority: c.priority, override_of_id: c.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct CreateRewriteRuleRequest { pub pattern: String, pub replacement: String, pub flag: Option, pub priority: i32, pub override_of_id: Option, } impl From for CreateRewriteRuleParams { fn from(r: CreateRewriteRuleRequest) -> Self { Self { location_id: Uuid::nil(), pattern: r.pattern, replacement: r.replacement, flag: r.flag, priority: r.priority, override_of_id: r.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct UpdateRewriteRuleRequest { pub location_id: Option, pub pattern: Option, pub replacement: Option, pub flag: Option>, pub priority: Option, pub override_of_id: Option>, } impl From for UpdateRewriteRuleParams { fn from(r: UpdateRewriteRuleRequest) -> Self { Self { location_id: r.location_id, pattern: r.pattern, replacement: r.replacement, flag: r.flag, priority: r.priority, override_of_id: r.override_of_id, } } } async fn list_rewrite_rules( State(svc): State>, Path(location_id): Path, ) -> Result>, AppError> { let rules = svc.list_by_location(location_id).await?; Ok(Json(rules.into_iter().map(Into::into).collect())) } async fn create_rewrite_rule( State(svc): State>, Path(location_id): Path, Json(body): Json, ) -> Result { let mut params = CreateRewriteRuleParams::from(body); params.location_id = location_id; let rule = svc.create(params).await?; Ok((StatusCode::CREATED, Json(RewriteRuleResponse::from(rule)))) } async fn get_rewrite_rule( State(svc): State>, Path(id): Path, ) -> Result, AppError> { let rule = svc.get(id).await?; Ok(Json(rule.into())) } async fn update_rewrite_rule( State(svc): State>, Path(id): Path, Json(body): Json, ) -> Result, AppError> { let rule = svc.update(id, body.into()).await?; Ok(Json(rule.into())) } async fn delete_rewrite_rule( State(svc): State>, Path(id): Path, ) -> Result { let deleted = svc.delete(id).await?; if deleted { Ok((StatusCode::NO_CONTENT,)) } else { Err(AppError::NotFound) } } pub(super) fn routes() -> ApiRouter { ApiRouter::new() .route( "/locations/{location_id}/rewrite-rules", axum::routing::get(list_rewrite_rules).post(create_rewrite_rule), ) .route( "/rewrite-rules/{id}", axum::routing::get(get_rewrite_rule) .put(update_rewrite_rule) .delete(delete_rewrite_rule), ) }